12.4. zipfile — 使用 ZIP 档案 — Python 文档

来自菜鸟教程
Python/docs/2.7/library/zipfile
跳转至:导航、​搜索

12.4. 压缩文件 — 使用 ZIP 档案

1.6 版中的新功能。


源代码: :source:`Lib/zipfile.py`



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

此模块当前不处理多磁盘 ZIP 文件。 它可以处理使用 ZIP64 扩展名的 ZIP 文件(即大小超过 4 GB 的 ZIP 文件)。 它支持对 ZIP 档案中的加密文件进行解密,但目前无法创建加密文件。 解密非常慢,因为它是用原生 Python 而不是 C 实现的。

该模块定义了以下项目:

exception zipfile.BadZipfile
错误 ZIP 文件(旧名称:zipfile.error)引发的错误。
exception zipfile.LargeZipFile
当 ZIP 文件需要 ZIP64 功能但尚未启用时引发的错误。
class zipfile.ZipFile
用于读取和写入 ZIP 文件的类。 有关构造函数的详细信息,请参阅 ZipFile 对象 部分。
class zipfile.PyZipFile
用于创建包含 Python 库的 ZIP 档案的类。
class zipfile.ZipInfo([filename[, date_time]])
用于表示档案成员信息的类。 此类的实例由 ZipFile 对象的 getinfo() 和 infolist() 方法返回。 zipfile 模块的大多数用户不需要创建这些,而只使用由该模块创建的那些。 filename 应该是归档成员的全名,而 date_time 应该是一个包含六个字段的元组,这些字段描述了最后一次修改文件的时间; 这些字段在 ZipInfo Objects 部分中进行了描述。
zipfile.is_zipfile(filename)

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

2.7 版更改: 支持文件和类文件对象。

zipfile.ZIP_STORED
未压缩归档成员的数字常量。
zipfile.ZIP_DEFLATED
通常的 ZIP 压缩方法的数字常量。 这需要 zlib 模块。 目前不支持其他压缩方法。

也可以看看

PKZIP 应用说明
所用格式和算法的创建者 Phil Katz 关于 ZIP 文件格式的文档。
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_STORED或ZIP_DEFLATED; 无法识别的值将导致 RuntimeError 升高。 如果指定了 ZIP_DEFLATED 但 zlib 模块不可用,则 RuntimeError 也会引发。 默认值为 ZIP_STORED。 如果 allowZip64 是 True zipfile 将创建使用 ZIP64 扩展名的 ZIP 文件,当 zipfile 大于 2 GB 时。 如果为 false(默认值),zipfile 将在 ZIP 文件需要 ZIP64 扩展名时引发异常。 默认情况下禁用 ZIP64 扩展,因为 Unix(InfoZIP 实用程序)上的默认 zip 和 unzip 命令不支持这些扩展。

在 2.7.1 版本更改: 如果文件是用 'a' 或 'w' 模式创建的,然后 关闭 没有向存档添加任何文件,空存档的适当 ZIP 结构将写入文件。

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

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

2.7 版新功能: 添加了使用 ZipFile 作为上下文管理器的功能。

ZipFile.close()
关闭存档文件。 您必须在退出程序之前调用 close(),否则基本记录将不会被写入。
ZipFile.getinfo(name)
返回一个 ZipInfo 对象,其中包含有关存档成员 name 的信息。 为当前未包含在存档中的名称调用 getinfo() 将引发 KeyError。
ZipFile.infolist()
为存档的每个成员返回一个包含 ZipInfo 对象的列表。 如果打开了现有存档,这些对象的顺序与它们在磁盘上实际 ZIP 文件中的条目顺序相同。
ZipFile.namelist()

按名称返回存档成员列表。

ZipFile.open(name[, mode[, pwd]])

从存档中提取成员作为类文件对象 (ZipExtFile)。 name 是存档中文件的名称,或 ZipInfo 对象。 mode 参数(如果包含)必须是以下之一:'r'(默认值)、'U' 或 'rU'。 选择 'U' 或 'rU' 将在只读对象中启用 通用换行符 支持。 pwd 是用于加密文件的密码。 在关闭的 ZipFile 上调用 open() 将引发 RuntimeError。

笔记

类文件对象是只读的,提供以下方法: read(), readline(), readlines(), __iter__() ]、next()。

笔记

如果 ZipFile 是通过将类文件对象作为第一个参数传递给构造函数来创建的,那么 open() 返回的对象将共享 ZipFile 的文件指针。 在这些情况下,在对 ZipFile 对象执行任何附加操作后,不应使用 open() 返回的对象。 如果 ZipFile 是通过将字符串(文件名)作为第一个参数传递给构造函数来创建的,那么 open() 将创建一个由 ZipExtFile 保存的新文件对象,允许它进行操作独立于 ZipFile。

笔记

open()、read() 和 extract() 方法可以采用文件名或 ZipInfo 对象。 当您尝试读取包含重名成员的 ZIP 文件时,您会很感激这一点。

2.6 版中的新功能。

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

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

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

2.6 版中的新功能。

笔记

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

ZipFile.extractall([path[, members[, pwd]]])

将存档中的所有成员提取到当前工作目录。 path 指定要提取到的不同目录。 members 是可选的,必须是 namelist() 返回的列表的子集。 pwd 是用于加密文件的密码。

警告

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

在 2.7.4 版更改: zipfile 模块试图阻止这种情况。 请参阅 extract() 注释。

2.6 版中的新功能。

ZipFile.printdir()
将存档的目录打印到 sys.stdout。
ZipFile.setpassword(pwd)

将 pwd 设置为提取加密文件的默认密码。

2.6 版中的新功能。

ZipFile.read(name[, pwd])

返回存档中文件 name 的字节。 name 是存档中文件的名称,或 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() 将引发 [ X143X]。 在关闭的 ZipFile 上调用 write() 将引发 RuntimeError。

笔记

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

笔记

存档名称应该相对于存档根,也就是说,它们不应以路径分隔符开头。

笔记

如果 arcname(或 filename,如果未给出 arcname)包含空字节,则存档中的文件名将在空字节处被截断。

ZipFile.writestr(zinfo_or_arcname, bytes[, compress_type])

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

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

笔记

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

2.7 版更改: compress_type 参数。

以下数据属性也可用:

ZipFile.debug
要使用的调试输出级别。 这可以从 0(默认,无输出)设置为 3(最多输出)。 调试信息写入sys.stdout。
ZipFile.comment
与 ZIP 文件关联的注释文本。 如果将注释分配给使用模式 'a' 或 'w' 创建的 ZipFile 实例,这应该是一个不超过 65535 字节的字符串。 当 close() 被调用时,超过这个长度的评论将在书面档案中被截断。


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

上次修改存档成员的时间和日期。 这是一个包含六个值的元组:

指数

价值

0

年份 (>= 1980)

1

月(以一位为单位)

2

一个月中的第几天(以一个为单位)

3

小时(从零开始)

4

分钟(从零开始)

5

秒(从零开始)

笔记

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

ZipInfo.compress_type
归档成员的压缩类型。
ZipInfo.comment
对单个存档成员的评论。
ZipInfo.extra
扩展字段数据。 PKZIP 应用笔记 包含一些关于此字符串中包含的数据的内部结构的注释。
ZipInfo.create_system
创建 ZIP 存档的系统。
ZipInfo.create_version
创建 ZIP 存档的 PKZIP 版本。
ZipInfo.extract_version
解压缩存档所需的 PKZIP 版本。
ZipInfo.reserved
必须为零。
ZipInfo.flag_bits
ZIP 标志位。
ZipInfo.volume
文件头的卷号。
ZipInfo.internal_attr
内部属性。
ZipInfo.external_attr
外部文件属性。
ZipInfo.header_offset
到文件头的字节偏移量。
ZipInfo.CRC
未压缩文件的 CRC-32。
ZipInfo.compress_size
压缩数据的大小。
ZipInfo.file_size
未压缩文件的大小。


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 是否有效。