How to unzip a file with Python 2.4?
Asked Answered
H

5

31

I'm having a hard time figuring out how to unzip a zip file with 2.4. extract() is not included in 2.4. I'm restricted to using 2.4.4 on my server.

Can someone please provide a simple code example?

Houlihan answered 18/10, 2011 at 11:34 Comment(4)
you can use "``" backtick operator or some other way execute system function and unzip your fileWanton
what do you want to do with a backtick? o.OZwick
If you found this question but are using a newer version of python do this: zfile = zipfile.ZipFile(file_to_extract) zfile.extractall(target_dir)Pleomorphism
@Fabian: You could skip the zFile variable and just have zipfile.ZipFile(file_to_extract).extractall(target_dir) - this suffers from the same problem that your code does, though, which is that you didn't close() the ZipFile afterwards which could lead to some OS problems (IE, you won't be able to delete the file, because it'll appear as in use by Python.)Chagres
D
52

You have to use namelist() and extract(). Sample considering directories

import zipfile
import os.path
import os
zfile = zipfile.ZipFile("test.zip")
for name in zfile.namelist():
  (dirname, filename) = os.path.split(name)
  print "Decompressing " + filename + " on " + dirname
  if not os.path.exists(dirname):
    os.makedirs(dirname)
  zfile.extract(name, dirname)
Dislike answered 18/10, 2011 at 11:49 Comment(5)
Ended up copying this one and noticed one little thing. At least if you zip your file with win7 "sendTo zip file" option, and your zip file contains nested folders, you need to change os.mkdir(dirname) -> os.makedirs(dirname). Otherwise you might get exceptions(No such file or directory), as zip file contains only leaf foldersLiving
What if name is a directory (not regular file)? I came across this case.Gadolinite
This solution is not going to work without further modifications. Two issues are : - using fd.write not in loop (so we may not write entire file if it is large). Using zfile.extract(name, concrete_dir) seems to be better - using os.mkdir will not create subdirectories. os.makedirs(concrete_dir) looks betterInextirpable
Use zfile.extract(name, '.') at last line instead to preserve zipped folder structure.Mccourt
@VinkoVrsalovic How do you save the files you've extracted?Gelasias
A
12

There's some problem with Vinko's answer (at least when I run it). I got:

IOError: [Errno 13] Permission denied: '01org-webapps-countingbeads-422c4e1/'

Here's how to solve it:

# unzip a file
def unzip(path):
    zfile = zipfile.ZipFile(path)
    for name in zfile.namelist():
        (dirname, filename) = os.path.split(name)
        if filename == '':
            # directory
            if not os.path.exists(dirname):
                os.mkdir(dirname)
        else:
            # file
            fd = open(name, 'w')
            fd.write(zfile.read(name))
            fd.close()
    zfile.close()
Angel answered 30/1, 2013 at 3:12 Comment(1)
Shouldn't that be fd = open(name, 'wb') in case some of the zipped files are images or otherwise binary files?Swellfish
S
3

Modifying Ovilia's answer so that you can specify the destination directory as well:

def unzip(zipFilePath, destDir):
    zfile = zipfile.ZipFile(zipFilePath)
    for name in zfile.namelist():
        (dirName, fileName) = os.path.split(name)
        if fileName == '':
            # directory
            newDir = destDir + '/' + dirName
            if not os.path.exists(newDir):
                os.mkdir(newDir)
        else:
            # file
            fd = open(destDir + '/' + name, 'wb')
            fd.write(zfile.read(name))
            fd.close()
    zfile.close()
Swellfish answered 23/4, 2013 at 19:23 Comment(0)
J
1

Not fully tested, but it should be okay:

import os
from zipfile import ZipFile, ZipInfo

class ZipCompat(ZipFile):
    def __init__(self, *args, **kwargs):
        ZipFile.__init__(self, *args, **kwargs)

    def extract(self, member, path=None, pwd=None):
        if not isinstance(member, ZipInfo):
            member = self.getinfo(member)
        if path is None:
            path = os.getcwd()
        return self._extract_member(member, path)

    def extractall(self, path=None, members=None, pwd=None):
        if members is None:
            members = self.namelist()
        for zipinfo in members:
            self.extract(zipinfo, path)

    def _extract_member(self, member, targetpath):
        if (targetpath[-1:] in (os.path.sep, os.path.altsep)
            and len(os.path.splitdrive(targetpath)[1]) > 1):
            targetpath = targetpath[:-1]
        if member.filename[0] == '/':
            targetpath = os.path.join(targetpath, member.filename[1:])
        else:
            targetpath = os.path.join(targetpath, member.filename)
        targetpath = os.path.normpath(targetpath)
        upperdirs = os.path.dirname(targetpath)
        if upperdirs and not os.path.exists(upperdirs):
            os.makedirs(upperdirs)
        if member.filename[-1] == '/':
            if not os.path.isdir(targetpath):
                os.mkdir(targetpath)
            return targetpath
        target = file(targetpath, "wb")
        try:
            target.write(self.read(member.filename))
        finally:
            target.close()
        return targetpath
Juliannjulianna answered 18/10, 2011 at 12:32 Comment(0)
C
-1

I am testing in Python 2.7.3rc2 and the the ZipFile.namelist() is not returning an entry with just the sub directory name for creating a sub directory, but only a list of file names with sub directory, as follows:

['20130923104558/control.json', '20130923104558/test.csv']

Thus the check

if fileName == '':

does not evaluate to True at all.

So I modified the code to check if the dirName exists inside destDir and to create dirName if it does not exist. File is extracted only if fileName part is not empty. So this should take care of the condition where a directory name can appear in ZipFile.namelist()

def unzip(zipFilePath, destDir):
    zfile = zipfile.ZipFile(zipFilePath)
    for name in zfile.namelist():
        (dirName, fileName) = os.path.split(name)
        # Check if the directory exisits
        newDir = destDir + '/' + dirName
        if not os.path.exists(newDir):
            os.mkdir(newDir)
        if not fileName == '':
            # file
            fd = open(destDir + '/' + name, 'wb')
            fd.write(zfile.read(name))
            fd.close()
    zfile.close()
Capitular answered 23/9, 2013 at 6:46 Comment(1)
This is not the answer if you are running python 2.7 see my comment on the questionPleomorphism

© 2022 - 2024 — McMap. All rights reserved.