12.4. zipfile — 使用 ZIP 档案 — Python 文档
12.4. 压缩文件 — 使用 ZIP 档案
1.6 版中的新功能。
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 模块。 目前不支持其他压缩方法。
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 是Truezipfile 将创建使用 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.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。
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 是否有效。