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