zipfile ---使用Zip存档¶
源代码: Lib/zipfile.py
zip文件格式是一种常见的存档和压缩标准。此模块提供创建、读取、写入、附加和列出zip文件的工具。本模块的任何高级使用都需要了解格式,如 PKZIP Application Note .
此模块当前不处理多磁盘zip文件。它可以处理使用zip64扩展名的zip文件(即大小超过4 gib的zip文件)。它支持对zip存档中的加密文件进行解密,但目前无法创建加密文件。解密非常慢,因为它是在本机python而不是C中实现的。
该模块定义了以下各项:
- exception zipfile.BadZipFile¶
- 为不正确的zip文件引发的错误。 - 3.2 新版功能. 
- exception zipfile.BadZipfile¶
- Alias - BadZipFile,以便与旧的python版本兼容。- 3.2 版后已移除. 
- exception zipfile.LargeZipFile¶
- 当zip文件需要zip64功能但尚未启用时引发的错误。 
- class zipfile.ZipFile
- 用于读取和写入zip文件的类。见节 zip文件对象 以获取构造函数详细信息。 
- class zipfile.Path
- 与pathlib兼容的zip文件包装。参见第节 路径对象 有关详细信息。 - 3.8 新版功能. 
- class zipfile.PyZipFile
- 用于创建包含python库的zip存档的类。 
- class zipfile.ZipInfo(filename='NoName', date_time=(1980, 1, 1, 0, 0, 0))¶
- 类,用于表示有关存档成员的信息。此类的实例由 - getinfo()和- infolist()方法- ZipFile物体。的大多数用户- zipfile模块不需要创建这些,但只使用由该模块创建的。 filename 应该是存档成员的全名,并且 date_time 应该是一个包含六个字段的元组,这些字段描述了文件最后一次修改的时间;这些字段在第节中进行了描述。 ZIPFIN对象 .
- zipfile.is_zipfile(filename)¶
- 返回 - True如果 filename 是基于其幻数的有效zip文件,否则返回- False. filename 也可能是文件或类似文件的对象。- 在 3.1 版更改: 支持文件和类似文件的对象。 
- zipfile.ZIP_STORED¶
- 未压缩存档成员的数字常量。 
- zipfile.ZIP_LZMA¶
- LZMA压缩方法的数值常量。这需要 - lzma模块。- 3.3 新版功能. - 注解 - Zip文件格式规范自2001年起支持bzip2压缩,自2006年起支持lzma压缩。但是,一些工具(包括旧的Python版本)不支持这些压缩方法,可能拒绝完全处理zip文件,或者无法提取单个文件。 
参见
- PKZIP Application Note
- 文件的压缩文件格式由菲尔卡茨,格式和算法的创建者使用。 
- Info-ZIP Home Page
- 有关info-zip项目的zip存档程序和开发库的信息。 
zip文件对象¶
- class zipfile.ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, compresslevel=None, *, strict_timestamps=True)¶
- 打开一个zip文件,其中 file 可以是文件(字符串)的路径、类似文件的对象或 path-like object . - 这个 mode 参数应为 - 'r'要读取现有文件,- 'w'要截断并写入新文件,- 'a'附加到现有文件,或- 'x'以独占方式创建和写入新文件。如果 mode 是- 'x'和 file 引用现有文件,a- FileExistsError将被引发。如果 mode 是- 'a'和 file 引用现有的zip文件,然后向其中添加其他文件。如果 file 不引用zip文件,则会将新的zip存档追加到该文件中。这是为了向另一个文件(如- python.exe)如果 mode 是- 'a'文件根本不存在,它是被创建的。如果 mode 是- 'r'或- 'a',文件应该是可查找的。- 压缩 是在写入存档文件时要使用的zip压缩方法,并且应该是 - ZIP_STORED,- ZIP_DEFLATED,- ZIP_BZIP2或- ZIP_LZMA;无法识别的值将导致- NotImplementedError被引发。如果- ZIP_DEFLATED,- ZIP_BZIP2或- ZIP_LZMA是指定的,但对应的模块 (- zlib,- bz2或- lzma)不可用,- RuntimeError提高了。默认值为- ZIP_STORED.- 如果 允许ZIP64 是 - True(默认)当zipfile大于4 gib时,zipfile将创建使用zip64扩展名的zip文件。如果是- false- zipfile当zip文件需要zip64扩展名时,将引发异常。- 这个 压缩能级 参数控制将文件写入存档时要使用的压缩级别。使用时 - ZIP_STORED或- ZIP_LZMA它没有效果。使用时- ZIP_DEFLATED整数- 0通过- 9被接受(见- zlib更多信息)。使用时- ZIP_BZIP2整数- 1通过- 9被接受(见- bz2更多信息)。- 这个 strict_timestamps 参数,设置为时 - False,允许压缩早于1980-01-01的文件,代价是将时间戳设置为1980-01-01。类似的行为发生在比2107-12-31更新的文件中,时间戳也被设置为限制。- 如果文件是用模式创建的 - 'w',- 'x'或- 'a'然后- closed不向存档添加任何文件,空存档的相应zip结构将写入该文件。- ZipFile也是一个上下文管理器,因此支持 - with语句。在这个例子中, MyZip 在- with语句的套件已完成---即使发生异常:- with ZipFile('spam.zip', 'w') as myzip: myzip.write('eggs.txt') - 3.2 新版功能: 增加了使用的能力 - ZipFile作为上下文管理器。- 在 3.4 版更改: 默认情况下,启用zip64扩展。 - 在 3.5 版更改: 添加了对无法访问的流的写入支持。增加了对 - 'x'模式。- 在 3.6 版更改: 以前是平原 - RuntimeError为无法识别的压缩值引发。- 在 3.6.2 版更改: 这个 file 参数接受 path-like object . - 在 3.7 版更改: 添加 压缩能级 参数。 - 3.8 新版功能: 这个 strict_timestamps 仅关键字参数 
- ZipFile.namelist()¶
- 按名称返回存档成员列表。 
- ZipFile.open(name, mode='r', pwd=None, *, force_zip64=False)¶
- 以类似二进制文件的对象访问存档的成员。 name 可以是存档中文件的名称,也可以是 - ZipInfo对象。这个 mode 参数(如果包含)必须为- 'r'(违约)或- 'w'. pwd 是用于解密加密zip文件的密码。- open()也是一个上下文管理器,因此支持- with声明:- with ZipFile('spam.zip') as myzip: with myzip.open('eggs.txt') as myfile: print(myfile.read()) - 用 mode - 'r'类似文件的对象 (- ZipExtFile)是只读的,并提供以下方法:- read(),- readline(),- readlines(),- seek(),- tell(),- __iter__(),- __next__(). 这些对象可以独立于zipfile操作。- 用 - mode='w',将返回一个可写的文件句柄,该句柄支持- write()方法。当可写文件句柄打开时,尝试读取或写入zip文件中的其他文件将引发- ValueError.- 写入文件时,如果事先不知道文件大小,但可能超过2 GiB,则通过 - force_zip64=True以确保头格式能够支持大型文件。如果预先知道文件大小,请构造- ZipInfo对象与- file_size设置,并将其用作 name 参数。- 在 3.6 版更改: 拆下的支架 - mode='U'. 使用- io.TextIOWrapper用于读取压缩文本文件 universal newlines 模式。- 在 3.6 版更改: - open()现在可以使用- mode='w'选择权。- 在 3.6 版更改: 调用 - open()在关闭的ZipFile上- ValueError. 以前,A- RuntimeError提高了。
- ZipFile.extract(member, path=None, pwd=None)¶
- 将存档中的成员提取到当前工作目录中; 成员 必须是其全名或 - ZipInfo对象。它的文件信息被尽可能准确地提取出来。 path 指定要提取到的其他目录。 成员 可以是文件名或- ZipInfo对象。 pwd 是用于加密文件的密码。- 返回创建的规范化路径(目录或新文件)。 - 注解 - 如果成员文件名是绝对路径,则驱动器/UNC SharePoint和前导(后)斜杠将被删除,例如: - ///foo/barbecomes- foo/baron Unix, and- C:\foo\barbecomes- foo\baron Windows. And all- ".."components in a member filename will be removed, e.g.:- ../../foo../../ba..rbecomes- foo../ba..r. On Windows illegal characters (- :, `` <- >,- |,- ",- ?和- *)替换为下划线 (- _)- 在 3.6 版更改: 调用 - extract()在关闭的ZipFile上- ValueError. 以前,A- RuntimeError提高了。- 在 3.6.2 版更改: 这个 path 参数接受 path-like object . 
- ZipFile.extractall(path=None, members=None, pwd=None)¶
- 将存档中的所有成员提取到当前工作目录。 path 指定要提取到的其他目录。 成员 是可选的,必须是由返回的列表的子集 - namelist(). pwd 是用于加密文件的密码。- 警告 - 未经事先检查,不得从不受信任的来源提取档案。文件可能是在 path ,例如,绝对文件名以 - "/"或带有两个点的文件名- "..". 本模块试图防止这种情况发生。见- extract()注意。- 在 3.6 版更改: 调用 - extractall()在关闭的ZipFile上- ValueError. 以前,A- RuntimeError提高了。- 在 3.6.2 版更改: 这个 path 参数接受 path-like object . 
- ZipFile.printdir()¶
- 将存档的目录打印到 - sys.stdout.
- ZipFile.setpassword(pwd)¶
- 集合 pwd 作为提取加密文件的默认密码。 
- ZipFile.read(name, pwd=None)¶
- 返回文件的字节 name 在存档中。 name 是存档中文件的名称,或 - ZipInfo对象。必须打开存档以供读取或追加。 pwd 是用于加密文件的密码,如果指定,它将覆盖默认密码设置- setpassword(). 调用- read()在使用压缩方法而不是- ZIP_STORED,- ZIP_DEFLATED,- ZIP_BZIP2或- ZIP_LZMA将提高- NotImplementedError.如果相应的压缩模块不可用,也会引发错误。- 在 3.6 版更改: 调用 - read()在关闭的ZipFile上- ValueError. 以前,A- RuntimeError提高了。
- ZipFile.testzip()¶
- 读取归档文件中的所有文件并检查其CRC和文件头。返回第一个错误文件的名称,否则返回 - None.- 在 3.6 版更改: 调用 - testzip()在关闭的ZipFile上- ValueError. 以前,A- RuntimeError提高了。
- ZipFile.write(filename, arcname=None, compress_type=None, compresslevel=None)¶
- 写入名为的文件 filename 到档案馆,给它一个档案馆的名字 弧名 (默认情况下,这将与 filename ,但没有驱动器号,并且删除了前导路径分隔符)。如果给出的话, compress_type 覆盖为 压缩 新项的构造函数的参数。同样地, 压缩能级 如果给定,将重写构造函数。存档必须以模式打开 - 'w',- 'x'或- 'a'.- 注解 - 存档名称应该相对于存档根目录,也就是说,它们不应该以路径分隔符开头。 - 注解 - 如果 - arcname(或)- filename如果- arcname未给定)包含空字节,存档中的文件名将在空字节处截断。- 在 3.6 版更改: 调用 - write()在使用模式创建的ZipFile上- 'r'或者一个关闭的zipfile将引发- ValueError. 以前,A- RuntimeError提高了。
- ZipFile.writestr(zinfo_or_arcname, data, compress_type=None, compresslevel=None)¶
- 将文件写入存档。内容是 data ,可以是 - str或A- bytes实例;如果是- str,首先将其编码为UTF-8。 zinfo_or_arcname 是将在存档中提供的文件名,还是- ZipInfo实例。如果它是一个实例,至少必须给出文件名、日期和时间。如果是名称,则日期和时间设置为当前日期和时间。必须以模式打开存档- 'w',- 'x'或- 'a'.- 如果给出的话, compress_type 覆盖为 压缩 新项的构造函数的参数,或 zinfo_or_arcname (如果那是 - ZipInfo实例)。同样地, 压缩能级 如果给定,将重写构造函数。- 注解 - 当通过 - ZipInfo实例作为 zinfo_or_arcname 参数,使用的压缩方法将是 compress_type 给定的成员- ZipInfo实例。默认情况下,- ZipInfo构造函数将此成员设置为- ZIP_STORED.- 在 3.2 版更改: 这个 compress_type 参数。 - 在 3.6 版更改: 调用 - writestr()在使用模式创建的ZipFile上- 'r'或者一个关闭的zipfile将引发- ValueError. 以前,A- RuntimeError提高了。
以下数据属性也可用:
- ZipFile.filename¶
- zip文件的名称。 
- ZipFile.debug¶
- 要使用的调试输出级别。这可能是从 - 0(默认,无输出)到- 3(最大输出)。调试信息写入- sys.stdout.
路径对象¶
- class zipfile.Path(root, at='')¶
- 从 - root压缩文件(可能是- ZipFile实例或- file适合传给- ZipFile构造函数)。- at指定此路径在zipfile中的位置,例如“dir/file.txt”、“dir/”或“”。默认为空字符串,指示根。
路径对象公开的以下功能 pathlib.Path 物体:
路径对象可以使用 / 运算符或 joinpath 。
- Path.name¶
- 最后一个路径组件。 
- Path.open(mode='r', *, pwd, **)¶
- 援引 - ZipFile.open()在当前路径上。允许通过支持的模式“r”、“w”、“rb”、“wb”打开读或写、文本或二进制文件。位置参数和关键字参数传递给- io.TextIOWrapper以文本形式打开,否则忽略。- pwd是- pwd参数到- ZipFile.open().- 在 3.9 版更改: 增加了对文本和二进制模式的支持。默认模式现在是文本。 
- Path.iterdir()¶
- 枚举当前目录的子目录。 
- Path.is_dir()¶
- 返回 - True如果当前上下文引用目录。
- Path.is_file()¶
- 返回 - True如果当前上下文引用文件。
- Path.exists()¶
- 返回 - True如果当前上下文引用了zip文件中的文件或目录。
- Path.read_text(*, **)¶
- 将当前文件读取为Unicode文本。位置参数和关键字参数传递给 - io.TextIOWrapper(除外)- buffer这是上下文所隐含的)。
- Path.read_bytes()¶
- 以字节形式读取当前文件。 
- Path.joinpath(*other)¶
- 返回一个新的路径对象,每个 其他 加入了参数。以下各项等效: - >>> Path(...).joinpath('child').joinpath('grandchild') >>> Path(...).joinpath('child', 'grandchild') >>> Path(...) / 'child' / 'grandchild' - 在 3.10 版更改: 在3.10之前, - joinpath没有记录并且只接受了一个参数。
PyZipFile对象¶
这个 PyZipFile 构造函数采用与 ZipFile 构造函数和一个附加参数, optimize .
- class zipfile.PyZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, optimize=- 1)¶
- 3.2 新版功能: 这个 optimize 参数。 - 在 3.4 版更改: 默认情况下,启用zip64扩展。 - 实例除了具有 - ZipFile物体:- writepy(pathname, basename='', filterfunc=None)¶
- 搜索文件 - *.py并将相应的文件添加到存档中。- 如果 optimize 参数到 - PyZipFile没有给予或- -1,对应的文件是- *.pyc文件,必要时编译。- 如果 optimize 参数到 - PyZipFile是- 0,- 1或- 2,仅限具有该优化级别的文件(请参见- compile())添加到存档中,必要时进行编译。- 如果 路径名 是一个文件,文件名必须以 - .py和(对应的- *.pyc)文件是在顶层添加的(没有路径信息)。如果 路径名 不是以结尾的文件- .py,A- RuntimeError将被引发。如果它是一个目录,而该目录不是包目录,则所有文件- *.pyc在顶层添加。如果目录是包目录,则全部- *.pyc以文件路径的形式添加到包名称下,如果任何子目录是包目录,则所有子目录都按顺序递归添加。- 基名 仅供内部使用。 - 菲尔特芬克 如果给定,则必须是采用单个字符串参数的函数。它将在添加到存档文件之前传递给每个路径(包括每个单独的完整文件路径)。如果 菲尔特芬克 返回一个假值,不会添加路径,如果路径是目录,则其内容将被忽略。例如,如果我们的测试文件都在 - test目录或以字符串开头- test_我们可以使用 菲尔特芬克 排除它们:- >>> zf = PyZipFile('myprog.zip') >>> def notests(s): ... fn = os.path.basename(s) ... return (not (fn == 'test' or fn.startswith('test_'))) >>> zf.writepy('myprog', filterfunc=notests) - 这个 - writepy()方法生成文件名如下的存档:- string.pyc # Top level name test/__init__.pyc # Package directory test/testall.pyc # Module test.testall test/bogus/__init__.pyc # Subpackage directory test/bogus/myfile.pyc # Submodule test.bogus.myfile - 3.4 新版功能: 这个 菲尔特芬克 参数。 - 在 3.6.2 版更改: 这个 路径名 参数接受 path-like object . - 在 3.7 版更改: 递归对目录项排序。 
 
ZIPFIN对象¶
的实例 ZipInfo 类由返回 getinfo() 和 infolist() 方法 ZipFile 物体。每个对象存储有关zip存档的单个成员的信息。
有一个类方法可以使 ZipInfo 文件系统文件的实例:
- classmethod ZipInfo.from_file(filename, arcname=None, *, strict_timestamps=True)¶
- 构建一个 - ZipInfo例如,文件系统上的一个文件,为将其添加到zip文件做准备。- filename 应该是文件系统上文件或目录的路径。 - 如果 弧名 已指定,它将用作存档中的名称。如果 弧名 未指定,名称将与 filename ,但删除了任何驱动器号和前导路径分隔符。 - 这个 strict_timestamps 参数,设置为时 - False,允许压缩早于1980-01-01的文件,代价是将时间戳设置为1980-01-01。类似的行为发生在比2107-12-31更新的文件中,时间戳也被设置为限制。- 3.6 新版功能. - 在 3.6.2 版更改: 这个 filename 参数接受 path-like object . - 3.8 新版功能: 这个 strict_timestamps 仅关键字参数 
实例具有以下方法和属性:
- ZipInfo.is_dir()¶
- 返回 - True如果此存档成员是目录。- 这将使用条目的名称:目录应始终以 - /.- 3.6 新版功能. 
- ZipInfo.filename¶
- 存档中文件的名称。 
- ZipInfo.date_time¶
- 上次修改存档成员的时间和日期。这是一个包含六个值的元组: - 索引 - 价值 - 0- 年份(>=1980) - 1- 月(以1为基础) - 2- 每月的某一天(基于一天) - 3- 小时(以零为基础) - 4- 分钟(从零开始) - 5- 秒(从零开始) - 注解 - zip文件格式不支持1980年以前的时间戳。 
- ZipInfo.compress_type¶
- 存档成员的压缩类型。 
- ZipInfo.extra¶
- 扩展字段数据。这个 PKZIP Application Note 包含有关此中包含的数据的内部结构的一些注释 - bytes对象。
- ZipInfo.create_system¶
- 创建zip存档的系统。 
- ZipInfo.create_version¶
- 创建zip存档的pkzip版本。 
- ZipInfo.extract_version¶
- 提取存档文件需要pkzip版本。 
- ZipInfo.reserved¶
- 必须是零。 
- ZipInfo.flag_bits¶
- 标记标志位。 
- ZipInfo.volume¶
- 文件头的卷号。 
- ZipInfo.internal_attr¶
- 内部属性。 
- ZipInfo.external_attr¶
- 外部文件属性。 
- ZipInfo.header_offset¶
- 文件头的字节偏移量。 
- ZipInfo.CRC¶
- 未压缩文件的CRC-32。 
- ZipInfo.compress_size¶
- 压缩数据的大小。 
- ZipInfo.file_size¶
- 未压缩文件的大小。 
命令行界面¶
这个 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
命令行选项¶
减压陷阱¶
由于下面列出的一些陷阱,zipfile模块中的提取可能会失败。
从文件本身¶
由于密码/CRC校验和/ZIP格式不正确或压缩方法/解密不受支持,解压缩可能会失败。
文件系统限制¶
超过不同文件系统的限制可能会导致解压缩失败。例如目录项中允许的字符、文件名的长度、路径名的长度、单个文件的大小和文件数等。
资源限制¶
内存或磁盘卷不足将导致解压缩失败。例如,减压炸弹 ZIP bomb )应用于可能导致磁盘卷耗尽的zipfile库。
中断¶
解压过程中的中断,如按下control-C或终止解压过程,可能会导致不完整的档案解压。
提取的默认行为¶
不知道默认的提取行为可能会导致意外的解压缩结果。例如,当提取同一个存档文件两次时,它会不经请求而覆盖文件。