12.4. zipfile —使用 ZIPFiles

1.6 版中的新Function。

源代码: Lib/zipfile.py


ZIP 文件格式是一种常见的存档和压缩标准。该模块提供了用于创建,读取,写入,附加和列出 ZIP 文件的工具。对该模块的任何高级用法都需要了解PKZIP 应用说明中定义的格式。

该模块当前不处理多磁盘 ZIP 文件。它可以处理使用 ZIP64extensions 的 ZIP 文件(即,大小超过 4 GB 的 ZIP 文件)。它支持对 ZIP 存档中的加密文件进行解密,但是当前无法创建加密文件。解密非常慢,因为它是在本机 Python 中而不是 C 中实现的。

该模块定义以下各项:

  • exception zipfile. BadZipfile

    • 错误的 ZIP 文件(旧名称:zipfile.error)引发的错误。
  • exception zipfile. LargeZipFile

    • 当 ZIP 文件需要 ZIP64 Function但尚未启用时引发的错误。
  • zipfile. ZipFile

    • 用于读取和写入 ZIP 文件的类。有关构造函数的详细信息,请参见ZipFile Objects部分。
  • 类别 zipfile. PyZipFile

    • 用于创建包含 Python 库的 ZIP 归档文件的类。
    • class * zipfile. ZipInfo([文件名 [,日期时间]])
    • 用于表示有关存档成员的信息的类。此类的实例由ZipFile个对象的getinfo()infolist()方法返回。 zipfile模块的大多数用户将不需要创建它们,而仅使用此模块创建的那些。 * filename 应该是存档成员的全名, date_time *应该是一个包含六个字段的 Tuples,这些字段描述了文件的最后修改时间; ZipInfo Objects部分中描述了这些字段。
  • zipfile. is_zipfile(* filename *)

    • 如果* filename *是基于其幻数的有效 ZIP 文件,则返回True,否则返回False文件名也可以是文件或类似文件的对象。

在 2.7 版中更改:支持文件和类似文件的对象。

  • zipfile. ZIP_STORED

    • 未压缩的存档成员的数字常数。
  • zipfile. ZIP_DEFLATED

    • 常用 ZIP 压缩方法的数字常数。这需要zlib模块。当前不支持其他压缩方法。

See also

  • PKZIP 应用说明

  • ZIP 文件格式的文档,作者是 Phil Katz,他是该格式和算法的创建者。

  • Info-ZIP 主页

  • 有关 Info-ZIP 项目的 ZIP 存档程序和开发库的信息。

12.4.1. ZipFile 对象

    • class * zipfile. ZipFile(* file * [,* mode * [,* compression * [,* allowZip64 *]]])
    • 打开一个 ZIP 文件,其中* file *可以是文件(字符串)的路径,也可以是类似文件的对象。 * mode 参数应为'r'以读取现有文件,为'w'以截断并写入新文件,或为'a'以附加到现有文件。如果 mode 'a' file 指的是现有的 ZIP 文件,则会向其添加其他文件。如果 file *不引用 ZIP 文件,则将新的 ZIP 存档附加到该文件。这是为了将 ZIP 存档添加到另一个文件(例如python.exe)。

在 2.6 版中进行了更改:如果* mode *为a并且该文件根本不存在,则会创建该文件。

  • compression 是编写归档文件时使用的 ZIP 压缩方法,应为ZIP_STOREDZIP_DEFLATED;无法识别的值将导致RuntimeError升高。如果指定了ZIP_DEFLATED,但zlib模块不可用,则也会引发RuntimeError。默认值为ZIP_STORED。如果 allowZip64 *为True,则 zipfile 将创建大于 2 GB 的 ZIP 文件,这些 ZIP 文件使用 ZIP64extensions。如果为假(默认值),则当 ZIP 文件需要 ZIP64extensions 时,zipfile将引发异常。默认情况下禁用 ZIP64 扩展,因为 Unix 上的默认 zipunzip 命令(InfoZIPUtil)不支持这些扩展。

在版本 2.7.1 中进行了更改:如果使用'a''w',然后使用closed模式创建了文件,而未将任何文件添加到存档中,则用于空存档的适当 ZIP 结构将被写入文件。

ZipFile 还是上下文 Management 器,因此支持with语句。在示例中,* myzip *在with语句的套件完成后关闭-即使发生异常:

with ZipFile('spam.zip', 'w') as myzip:
    myzip.write('eggs.txt')

2.7 版的新Function:添加了使用ZipFile作为上下文 Management 器的Function。

  • ZipFile. close ( )

    • 关闭存档文件。您必须先退出close(),然后退出程序,否则基本记录将不会被写入。
  • ZipFile. getinfo(* name *)

    • 返回一个ZipInfo对象,其中包含有关存档成员* name *的信息。调用getinfo()以获取当前未包含在 Files 中的名称将引发KeyError
  • ZipFile. infolist ( )

    • 为 Files 的每个成员返回一个包含ZipInfo对象的列表。如果打开了现有存档,则对象的 Sequences 与它们在磁盘上实际 ZIP 文件中的条目的 Sequences 相同。
  • ZipFile. namelist ( )

    • 按名称返回存档成员列表。
  • ZipFile. open(* name * [,* mode * [,* pwd *]])
    • 从存档中提取一个成员作为文件状对象(ZipExtFile)。 * name *是 Files 中文件的名称,即ZipInfo对象。 * mode *参数(如果包括)必须为以下之一:'r'(默认值),'U''rU'。选择'U''rU'将在只读对象中启用universal newline支持。 * pwd *是用于加密文件的密码。在关闭的 ZipFile 上调用open()将引发RuntimeError

Note

类文件对象是只读的,并提供以下方法:read()readline()readlines()iter()next()

Note

如果 ZipFile 是pass将类似文件的对象作为构造函数的第一个参数传递而创建的,则open()返回的对象将共享 ZipFile 的文件指针。在这种情况下,在 ZipFile 对象上执行任何其他操作后,不应使用open()返回的对象。如果 ZipFile 是pass将字符串(文件名)作为构造函数的第一个参数传入而创建的,则open()将创建一个新文件对象,该对象将由 ZipExtFile 保存,从而使其能够独立于 ZipFile 进行操作。

Note

open()read()extract()方法可以使用文件名或ZipInfo对象。当您try读取包含名称重复的成员的 ZIP 文件时,您将不胜感激。

2.6 版的新Function。

  • ZipFile. extract(* member * [,* path * [,* pwd *]])
    • 从存档中提取成员到当前工作目录; 成员必须是其全名或ZipInfo对象)。尽可能准确地提取其文件信息。 * path *指定要提取到的其他目录。 * member *可以是文件名或ZipInfo对象。 * pwd *是用于加密文件的密码。

返回创建的规范化路径(目录或新文件)。

2.6 版的新Function。

Note

如果成员文件名是绝对路径,则将删除驱动器/ UNC 共享点和前导(反)斜杠,例如:在 Unix 上///foo/bar变为foo/bar,在 Windows 上C:\foo\bar变为foo\bar。并且成员文件名中的所有".."组件将被删除,例如../../foo../../ba..r变为foo../ba..r。在 Windows 上,非法字符(:<>|"?*)下划线(_)代替。

  • ZipFile. extractall([* path * [,* members * [,* pwd *]]])
    • 将所有成员从存档提取到当前工作目录。 * path *指定要提取到的其他目录。 * members *是可选的,并且必须是namelist()返回的列表的子集。 * pwd *是用于加密文件的密码。

Warning

未经事先检查,切勿从不受信任的来源中提取 Files。文件可能是在* path *之外创建的,例如具有以"/"开头的绝对文件名或带有两个点".."的文件名的成员。

在版本 2.7.4 中更改:zipfile 模块try阻止这种情况。请参阅extract()注意。

2.6 版的新Function。

  • ZipFile. printdir ( )

    • 将目录的目录打印到sys.stdout
  • ZipFile. setpassword(* pwd *)

    • 将* pwd *设置为默认密码以提取加密文件。

2.6 版的新Function。

  • ZipFile. read(* name * [,* pwd *])
    • 返回 Files 中* name *文件的字节。 * name *是 Files 中文件的名称,即ZipInfo对象。必须打开存档以进行读取或追加。 * pwd *是用于加密文件的密码,如果指定了密码,它将覆盖用setpassword()设置的默认密码。在关闭的 ZipFile 上调用read()将引发RuntimeError

在 2.6 版中进行了更改:添加了* pwd name *现在可以是ZipInfo对象。

  • ZipFile. testzip ( )

    • 读取存档中的所有文件,并检查其 CRC 和文件头。返回第一个错误文件的名称,否则返回None。在关闭的 ZipFile 上调用testzip()将引发RuntimeError
  • ZipFile. write(* filename * [,* arcname * [,* compress_type *]])

    • 将名为* filename 的文件写入存档,并为其指定存档名称 arcname (默认情况下,该名称与 filename 相同,但不带驱动器号,并且删除前导路径分隔符)。如果给定, compress_type 将为新条目的构造函数覆盖为 compression *参数指定的值。存档必须以'w''a'模式打开–在以'r'模式创建的 ZipFile 上调用write()将引发RuntimeError。在关闭的 ZipFile 上调用write()将引发RuntimeError

Note

没有用于 ZIP 文件的正式文件名编码。如果您具有 unicode 文件名,则必须将它们转换为所需编码的字节字符串,然后再将其传递给write()。 WinZip 将所有文件名解释为以 CP437(也称为 DOS Latin)编码。

Note

存档名称应相对于存档根目录,即,它们不应以路径分隔符开头。

Note

如果arcname(或filename,如果未提供arcname)包含一个空字节,则存档中文件的名称将在该空字节处被截断。

  • ZipFile. writestr(* zinfo_or_arcname bytes * [,* compress_type *])
    • 将字符串* bytes *写入存档; * zinfo_or_arcname *是将在归档文件中给出的文件名或ZipInfo实例。如果是实例,则至少必须提供文件名,日期和时间。如果是名称,则将日期和时间设置为当前日期和时间。必须以'w''a'模式打开存档–在以'r'模式创建的 ZipFile 上调用writestr()将引发RuntimeError。在关闭的 ZipFile 上调用writestr()将引发RuntimeError

如果给定,* compress_type 会为新条目的构造函数或 zinfo_or_arcname (如果是ZipInfo实例)覆盖为 compression *参数赋予的值。

Note

当将ZipInfo实例作为* zinfo_or_arcname 参数传递时,使用的压缩方法将是给定ZipInfo实例的 compress_type *成员中指定的压缩方法。默认情况下,ZipInfo构造函数将此成员设置为ZIP_STORED

在 2.7 版中进行了更改:* compress_type *参数。

以下数据属性也可用:

  • ZipFile. debug

    • 要使用的调试输出级别。可以将其设置为0(默认,无输出)到3(最多输出)。调试信息被写入sys.stdout
  • ZipFile. comment

    • 与 ZIP 文件关联的 Comments 文本。如果将 Comments 分配给以模式“ a”或“ w”创建的ZipFile实例,则该字符串不得超过 65535 个字节。调用close()时,长于 Comments 的 Comments 将在书面存档中被截断。

12.4.2. PyZipFile 对象

PyZipFile构造函数采用与ZipFile构造函数相同的参数。除了ZipFile对象的实例之外,实例还具有一种方法。

  • PyZipFile. writepy(* pathname * [,* basename *])
    • 搜索文件*.py并将相应的文件添加到存档中。相应的文件是*.pyo文件(如果可用),否则是*.pyc文件,如果需要的话可以进行编译。如果路径名是文件,则文件名必须以.py结尾,并且仅在顶层添加(对应的*.py[co])文件(没有路径信息)。如果路径名不是以.py结尾的文件,则将引发RuntimeError。如果它是目录,并且该目录不是包目录,那么所有文件*.py[co]都将添加到顶层。如果该目录是程序包目录,那么所有*.py[co]都将作为文件路径添加到程序包名下,如果子目录是程序包目录,则将所有这些都递归添加。 * basename *仅供内部使用。 writepy()方法使用以下文件名进行归档:
string.pyc                                # Top level name
test/__init__.pyc                         # Package directory
test/test_support.pyc                          # Module test.test_support
test/bogus/__init__.pyc                   # Subpackage directory
test/bogus/myfile.pyc                     # Submodule test.bogus.myfile

12.4.3. ZipInfo 对象

ZipInfo类的实例由ZipFile对象的getinfo()infolist()方法返回。每个对象都存储有关 ZIP 存档的单个成员的信息。

实例具有以下属性:

  • ZipInfo. filename

    • 存档中文件的名称。
  • ZipInfo. date_time

    • 最后一次修改存档成员的时间和日期。这是六个值的 Tuples:
IndexValue
0年(> = 1980)
1Month (one-based)
2一个月中的某天(基于 1 天)
3Hours (zero-based)
4Minutes (zero-based)
5Seconds (zero-based)

Note

ZIP 文件格式不支持 1980 年之前的时间戳。

  • ZipInfo. compress_type

    • 存档成员的压缩类型。
  • ZipInfo. comment

    • 为单个存档成员发表 Comment。
  • ZipInfo. extra

    • 扩展字段数据。 PKZIP 应用说明包含有关此字符串中数据内部结构的一些 Comments。
  • ZipInfo. create_system

    • 创建 ZIP 归档文件的系统。
  • ZipInfo. create_version

    • 创建 ZIP 存档的 PKZIP 版本。
  • ZipInfo. extract_version

    • 提取存档所需的 PKZIP 版本。
  • ZipInfo. reserved

    • 必须为零。
  • ZipInfo. flag_bits

    • ZIP 标志位。
  • ZipInfo. volume

    • 文件头的卷号。
  • ZipInfo. internal_attr

    • Internal attributes.
  • ZipInfo. external_attr

    • 外部文件属性。
  • ZipInfo. header_offset

    • 文件头的字节偏移量。
  • ZipInfo. CRC

    • 未 zipfile 的 CRC-32.
  • ZipInfo. compress_size

    • 压缩数据的大小。
  • ZipInfo. file_size

    • 未 zipfile 的大小。

12.4.4. 命令行界面

zipfile模块提供了一个简单的命令行界面,可与 ZIP 存档进行交互。

如果要创建新的 ZIP 存档,请在-c选项后指定其名称,然后列出应包括的文件名:

$ python -m zipfile -c monty.zip spam.txt eggs.txt

传递目录也是可以的:

$ python -m zipfile -c monty.zip life-of-brian_1979/

如果要将 ZIP 存档解压缩到指定目录中,请使用-e选项:

$ python -m zipfile -e monty.zip target-dir/

有关 ZIP 存档中文件的列表,请使用-l选项:

$ python -m zipfile -l monty.zip

12.4.4.1. 命令行选项

  • -l <zipfile>

    • 列出 zipfile 中的文件。
  • -c <zipfile> <source1> ... <sourceN>

    • 从源文件创建 zipfile。
  • -e <zipfile> <output_dir>

    • 将 zipfile 解压缩到目标目录。
  • -t <zipfile>

    • 测试 zipfile 是否有效。