【问题标题】:Selective extracting and opening for zipfile in pythonpython中zipfile的选择性提取和打开
【发布时间】:2014-01-31 07:06:43
【问题描述】:

从文档看来,可以使用原生 python 中的 zipfile 模块执行选择性文件提取和打开,http://docs.python.org/2/library/zipfile using

ZipFile.extract(member[, path[, pwd]])

从存档中提取一个成员到当前工作目录; member 必须是其全名或 ZipInfo 对象)。它的文件 尽可能准确地提取信息。路径指定一个 解压到不同的目录。 member 可以是文件名或 ZipInfo 对象。 pwd 是用于加密文件的密码。

我有一个这样的压缩文件foobar.zip:

foobar.zip\
  \foo
      \a.txt
      \b.txt
  \bar
      \b.txt
      \c.txt

我尝试从 .zip 文件的单个子目录中提取文件,但有时它什么也不打印:

import zipfile
with zipfile.ZipFile('foobar.zip','r') as inzipfile:
  for infile in inzipfile.namelist():
    if 'foo' in os.path.split(infile)[0]:
      print inzipfile.open(infile,'r').read()

我已尝试提供我可能想要提取的选定文件的列表,但有时它也不会打印任何内容。

wanted = ['a.txt', 'b.txt']
import zipfile
with zipfile.ZipFile('foobar.zip','r') as inzipfile:
  for infile in inzipfile.namelist():
    if os.path.split(infile)[1] in wanted:
      print inzipfile.open(infile,'r').read()

已编辑: 代码或我读取文件的方式没有任何问题。我认为我的 zipfile 有问题导致 schroedinbug 有时我的子目录文件无法打开,inzipfile.open(infile,'r').read() 返回 None。现在它会提取、打开并打印文件的内容。

知道如何在 python 代码中检查 .zip 文件中的所有文件是否可以使用上述选择性提取/打开方法打开?

我还能如何执行 zipfile 的选择性提取/打开? 有没有更 Pythonic 的方法?

【问题讨论】:

    标签: python if-statement file-io zip zipfile


    【解决方案1】:

    你的代码有问题。它正在打开并读取也在inzipfile.namelist() 中的文件夹名称。您可以通过以下方式看到这一点:

    print inzipfile.namelist()
    

    将输出:

    ['foobar/bar/', 'foobar/bar/b.txt', 'foobar/bar/c.txt', 'foobar/foo/', 
     'foobar/foo/a.txt', 'foobar/foo/b.txt', 'foobar/']
    

    查看它的另一种方式是使用inzipfile.printdir(),这应该会导致打印以下内容:

    File Name                                             Modified             Size
    foobar/bar/                                    2014-01-12 08:53:36            0
    foobar/bar/b.txt                               2014-01-12 08:54:08           60
    foobar/bar/c.txt                               2014-01-12 08:54:28           60
    foobar/foo/                                    2014-01-12 08:53:02            0
    foobar/foo/a.txt                               2014-01-12 08:55:04           60
    foobar/foo/b.txt                               2014-01-12 08:55:24           60
    foobar/                                        2014-01-12 08:52:32            0
    

    请注意,在这两种情况下,所有文件夹条目的名称都以/character 结尾。您可以将其用作检测它们的简单方法:

    import os
    import zipfile
    
    with zipfile.ZipFile('foobar.zip', 'r') as inzipfile:
        for infile in (name for name in inzipfile.namelist() if name[-1] != '/'):
            if 'foo' in os.path.split(infile)[0]:
                print inzipfile.open(infile,'r').read(),
    

    同样:

    wanted = {'a.txt', 'b.txt'}  # use a set, it's faster for testing membership
    import zipfile
    with zipfile.ZipFile('foobar.zip','r') as inzipfile:
        for infile in (name for name in inzipfile.namelist() if name[-1] != '/'):
            if os.path.split(infile)[1] in wanted:
              print inzipfile.open(infile,'r').read()
    

    我能想到的检查档案的所有 [file] 成员是否都可以打开的唯一方法是实际尝试对每个成员执行此操作:

    def check_files(zipfilename):
        """ Check and see if all members of a .zip archive can be opened.
            Beware of vacuous truth - all members of an empty archive can be opened
        """
        def can_open(archive, membername):
            try:
                archive.open(membername, 'r')  # return value ignored
            except (RuntimeError, zipfile.BadZipfile, zipfile.LargeZipFile):
                return False
            return True
    
        with zipfile.ZipFile(zipfilename, 'r') as archive:
            return all(can_open(archive, membername)
                        for membername in (
                            name for name in archive.namelist() if name[-1] != '/'))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2018-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多