【问题标题】:How to unzip a file with Python 2.4?如何使用 Python 2.4 解压缩文件?
【发布时间】:2011-12-10 00:44:39
【问题描述】:

我很难弄清楚如何使用 2.4 解压缩 zip 文件。 extract() 不包含在 2.4 中。我被限制在我的服务器上使用 2.4.4。

有人可以提供一个简单的代码示例吗?

【问题讨论】:

  • 你可以使用"``" 反引号或者其他方式执行系统函数并解压你的文件
  • 你想用反引号做什么? o.O
  • 如果您发现了这个问题,但使用的是较新版本的 python,请执行以下操作:zfile = zipfile.ZipFile(file_to_extract) zfile.extractall(target_dir)
  • @Fabian:您可以跳过 zFile 变量而只使用 zipfile.ZipFile(file_to_extract).extractall(target_dir) - 这与您的代码存在相同的问题,即您没有 close() @987654324 @ 之后可能会导致一些操作系统问题(IE,您将无法删除该文件,因为它会显示为 Python 正在使用。)

标签: python zip zipfile python-2.4


【解决方案1】:

您必须使用namelist()extract()。考虑目录的示例

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)

【讨论】:

  • 最后复制了这个并注意到了一件小事。至少如果您使用 win7“sendTo zip 文件”选项压缩文件,并且您的 zip 文件包含嵌套文件夹,则需要更改 os.mkdir(dirname) -> os.makedirs(dirname)。否则你可能会遇到异常(没有这样的文件或目录),因为 zip 文件只包含叶子文件夹
  • 如果name 是一个目录(不是普通文件)怎么办?我遇到了这种情况。
  • 如果不做进一步修改,此解决方案将无法工作。两个问题是: - 不在循环中使用 fd.write(所以如果文件很大,我们可能不会写入整个文件)。使用 zfile.extract(name, concrete_dir) 似乎更好——使用 os.mkdir 不会创建子目录。 os.makedirs(concrete_dir) 看起来更好
  • 在最后一行使用 zfile.extract(name, '.') 来保留压缩文件夹结构。
  • @VinkoVrsalovic 如何保存提取的文件?
【解决方案2】:

我在 Python 2.7.3rc2 中进行测试,ZipFile.namelist() 没有返回仅包含用于创建子目录的子目录名称的条目,而是仅返回带有子目录的文件名列表,如下所示:

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

因此检查

if fileName == '':

根本不评估为True

所以我修改了代码以检查dirName 是否存在于destDir 中,如果不存在则创建dirName。仅当fileName 部分不为空时才会提取文件。所以这应该注意目录名称可以出现在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()

【讨论】:

  • 如果您正在运行 python 2.7,这不是答案,请参阅我对问题的评论
【解决方案3】:

修改Ovilia's answer,以便您也可以指定目标目录:

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()

【讨论】:

    【解决方案4】:

    Vinko 的回答有些问题(至少在我运行它时)。我得到了:

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

    解决方法如下:

    # 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()
    

    【讨论】:

    • 不应该是fd = open(name, 'wb'),以防某些压缩文件是图像或其他二进制文件?
    【解决方案5】:

    没有经过全面测试,但应该没问题:

    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
    

    【讨论】:

      猜你喜欢
      • 2011-09-01
      • 2015-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多