On this page
zipfile —使用 ZIPFiles
源代码: Lib/zipfile.py
ZIP 文件格式是一种常见的存档和压缩标准。该模块提供了用于创建,读取,写入,附加和列出 ZIP 文件的工具。对该模块的任何高级用法都需要了解PKZIP 应用说明中定义的格式。
该模块当前不处理多磁盘 ZIP 文件。它可以处理使用 ZIP64extensions 的 ZIP 文件(即,大小超过 4 GiB 的 ZIP 文件)。它支持对 ZIP 存档中的加密文件进行解密,但是当前无法创建加密文件。解密非常慢,因为它是在本机 Python 中而不是 C 中实现的。
该模块定义以下各项:
- exception 
zipfile.BadZipFile- 错误的 ZIP 文件引发的错误。
 
 
3.2 版中的新Function。
- exception 
zipfile.BadZipfile- BadZipFile的别名,用于与旧版本的 Python 兼容。
 
 
从 3.2 版开始不推荐使用。
exception
zipfile.LargeZipFile- 当 ZIP 文件需要 ZIP64 Function但尚未启用时引发的错误。
 
类
zipfile.ZipFile- 用于读取和写入 ZIP 文件的类。有关构造函数的详细信息,请参见ZipFile Objects部分。
 
类
zipfile.Path- zip 文件的 pathlib 兼容包装器。有关详细信息,请参见第Path Objects节。
 
3.8 版的新Function。
类
zipfile.PyZipFile- 用于创建包含 Python 库的 ZIP 归档文件的类。
 
- 
    
- class * 
zipfile.ZipInfo(* filename ='NoName', date_time =(1980 , 1 , 1 , 0 , 0 , 0)*) 
- 用于表示有关存档成员的信息的类。此类的实例由ZipFile个对象的getinfo()和infolist()方法返回。 zipfile模块的大多数用户将不需要创建它们,而仅使用此模块创建的那些。 * filename 应该是存档成员的全名, date_time *应该是一个包含六个字段的 Tuples,这些字段描述了文件的最后修改时间; ZipInfo Objects部分中描述了这些字段。
 
 - class * 
 zipfile.is_zipfile(* filename *)- 如果* filename *是基于其幻数的有效 ZIP 文件,则返回
True,否则返回False。 文件名也可以是文件或类似文件的对象。 
- 如果* filename *是基于其幻数的有效 ZIP 文件,则返回
 
在版本 3.1 中更改:支持文件和类似文件的对象。
zipfile.ZIP_STORED- 未压缩的存档成员的数字常数。
 
zipfile.ZIP_DEFLATED- 常用 ZIP 压缩方法的数字常数。这需要zlib模块。
 
zipfile.ZIP_BZIP2- BZIP2 压缩方法的数字常数。这需要bz2模块。
 
版本 3.3 中的新Function。
zipfile.ZIP_LZMA- LZMA 压缩方法的数字常数。这需要lzma模块。
 
版本 3.3 中的新Function。
Note
ZIP 文件格式规范自 2001 年以来就包括对 bzip2 压缩的支持,从 2006 年以来就包括对 LZMA 压缩的支持。但是,某些工具(包括较旧的 Python 版本)不支持这些压缩方法,或者可能完全拒绝处理 ZIP 文件,或者无法提取单个文件。
See also
ZIP 文件格式的文档,作者是 Phil Katz,他是该格式和算法的创建者。
有关 Info-ZIP 项目的 ZIP 存档程序和开发库的信息。
ZipFile Objects
- 
    
- class * 
zipfile.ZipFile(* file , mode ='r', compression = ZIP_STORED , allowZip64 = True , compresslevel = None ,**,* strict_timestamps = True *) 
- 打开一个 ZIP 文件,其中* file *可以是文件(字符串),类似文件的对象或path-like object的路径。
 
 - class * 
 
mode 参数应为
'r'以读取现有文件,'w'截断并写入新文件,'a'附加到现有文件或'x'以专门创建和写入新文件。如果 mode 为'x'且 file 表示现有文件,则将引发FileExistsError。如果 mode 是'a',并且 file 指的是现有的 ZIP 文件,则会向其中添加其他文件。如果 file 不引用 ZIP 文件,则将新的 ZIP 存档附加到该文件。这是为了将 ZIP 存档添加到另一个文件(例如python.exe)。如果 mode 为'a'并且该文件根本不存在,则会创建该文件。如果 mode *是'r'或'a',则该文件应可搜索。compression *是编写归档文件时使用的 ZIP 压缩方法,应为ZIP_STORED,ZIP_DEFLATED,ZIP_BZIP2或ZIP_LZMA;无法识别的值将导致NotImplementedError升高。如果指定了ZIP_DEFLATED,ZIP_BZIP2或ZIP_LZMA,但是相应的模块(zlib,bz2或lzma)不可用,则会引发RuntimeError。默认值为ZIP_STORED。
如果* allowZip64 *为True(默认值),则 zipfile 会创建一个 ZIP 文件,当 zipfile 大于 4 GiB 时,将使用 ZIP64extensions。如果是false,则zipfile将引发异常,当 ZIP 文件需要 ZIP64extensions 时。
compresslevel *参数控制将文件写入存档时要使用的压缩级别。使用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 还是上下文 Management 器,因此支持with语句。在示例中,* myzip *在with语句的套件完成后关闭-即使发生异常:
with ZipFile('spam.zip', 'w') as myzip:
    myzip.write('eggs.txt')
  版本 3.2 中的新Function:添加了使用ZipFile作为上下文 Management 器的Function。
在版本 3.3 中进行了更改:添加了对bzip2和lzma压缩的支持。
在版本 3.4 中更改:默认情况下启用 ZIP64 扩展。
在版本 3.5 中进行了更改:添加了对写入不可搜索流的支持。添加了对'x'模式的支持。
在版本 3.6 中进行了更改:以前,对于无法识别的压缩值,提出了一个普通的RuntimeError。
在版本 3.6.2 中更改:* file *参数接受path-like object。
在 3.7 版中进行了更改:添加* compresslevel *参数。
3.8 版中的新Function:* strict_timestamps *仅关键字参数
ZipFile.close( )- 关闭存档文件。您必须先退出close(),然后退出程序,否则基本记录将不会被写入。
 
ZipFile.getinfo(* name *)ZipFile.infolist( )- 为 Files 的每个成员返回一个包含ZipInfo对象的列表。如果打开了现有存档,则对象的 Sequences 与它们在磁盘上实际 ZIP 文件中的条目的 Sequences 相同。
 
ZipFile.namelist( )- 按名称返回存档成员列表。
 
ZipFile.open(* name , mode ='r', pwd = None ,**,* force_zip64 = False *)- 以类似于二进制文件的对象的形式访问存档的成员。 * name *可以是存档中文件的名称,也可以是ZipInfo对象。 * mode *参数(如果包含)必须为
'r'(默认值)或'w'。 * pwd *是用于解密加密的 ZIP 文件的密码。 
- 以类似于二进制文件的对象的形式访问存档的成员。 * name *可以是存档中文件的名称,也可以是ZipInfo对象。 * mode *参数(如果包含)必须为
 
open()也是上下文 Management 器,因此支持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()方法的可写文件句柄。打开可写文件句柄时,try在 ZIP 文件中读取或写入其他文件将引发ValueError。
写入文件时,如果文件大小事先未知,但可能超过 2 GiB,则传递force_zip64=True以确保头格式能够支持大文件。如果文件大小事先已知,则构造一个file_size设置的ZipInfo对象,并将其用作* name *参数。
在版本 3.6 中更改:删除了对mode='U'的支持。使用io.TextIOWrapper以universal newlines模式读取压缩的文本文件。
在 3.6 版中进行了更改:open()现在可用于passmode='w'选项将文件写入存档。
在版本 3.6 中进行了更改:在关闭的 ZipFile 上调用open()将引发ValueError。以前,提出了RuntimeError。
ZipFile.extract(* member , path = None , pwd = None *)
返回创建的规范化路径(目录或新文件)。
Note
如果成员文件名是绝对路径,则将删除驱动器/ UNC 共享点和前导(反)斜杠,例如:在 Unix 上///foo/bar变为foo/bar,在 Windows 上C:\foo\bar变为foo\bar。并且成员文件名中的所有".."组件将被删除,例如../../foo../../ba..r变为foo../ba..r。在 Windows 上,非法字符(:,<,>,|,",?和*)被下划线(_)代替。
在版本 3.6 中进行了更改:在关闭的 ZipFile 上调用extract()将引发ValueError。以前,提出了RuntimeError。
在版本 3.6.2 中更改:* path *参数接受path-like object。
ZipFile.extractall(* path = None , members = None , pwd = None *)- 将所有成员从存档提取到当前工作目录。 * path *指定要提取到的其他目录。 * members *是可选的,并且必须是namelist()返回的列表的子集。 * pwd *是用于加密文件的密码。
 
Warning
未经事先检查,切勿从不受信任的来源中提取 Files。文件可能是在* path *之外创建的,例如具有以"/"开头的绝对文件名或带有两个点".."的文件名的成员。该模块试图防止这种情况。请参阅extract()注意。
在版本 3.6 中进行了更改:在关闭的 ZipFile 上调用extractall()将引发ValueError。以前,提出了RuntimeError。
在版本 3.6.2 中更改:* path *参数接受path-like object。
ZipFile.printdir( )- 将目录的目录打印到
sys.stdout。 
- 将目录的目录打印到
 ZipFile.setpassword(* pwd *)- 将* pwd *设置为默认密码以提取加密文件。
 
ZipFile.read(* name , pwd = None *)- 返回 Files 中* name *文件的字节。 * name *是 Files 中文件的名称,即ZipInfo对象。必须打开存档以进行读取或追加。 * pwd *是用于加密文件的密码,如果指定了密码,它将覆盖用setpassword()设置的默认密码。在使用ZIP_STORED,ZIP_DEFLATED,ZIP_BZIP2或ZIP_LZMA以外的压缩方法的 ZipFile 上调用read()将引发NotImplementedError。如果相应的压缩模块不可用,也会引发错误。
 
在版本 3.6 中进行了更改:在关闭的 ZipFile 上调用read()将引发ValueError。以前,提出了RuntimeError。
ZipFile.testzip( )- 读取存档中的所有文件,并检查其 CRC 和文件头。返回第一个错误文件的名称,否则返回
None。 
- 读取存档中的所有文件,并检查其 CRC 和文件头。返回第一个错误文件的名称,否则返回
 
在版本 3.6 中进行了更改:在关闭的 ZipFile 上调用testzip()将引发ValueError。以前,提出了RuntimeError。
ZipFile.write(* filename , arcname = None , compress_type = None , compresslevel = None *)- 将名为* filename 的文件写入存档,并为其指定存档名称 arcname (默认情况下,该名称与 filename 相同,但不带驱动器号,并且删除前导路径分隔符)。如果给定, compress_type 将为新条目的构造函数覆盖为 compression 参数指定的值。同样,如果指定, compresslevel *将覆盖构造函数。存档必须以
'w','x'或'a'模式打开。 
- 将名为* filename 的文件写入存档,并为其指定存档名称 arcname (默认情况下,该名称与 filename 相同,但不带驱动器号,并且删除前导路径分隔符)。如果给定, compress_type 将为新条目的构造函数覆盖为 compression 参数指定的值。同样,如果指定, compresslevel *将覆盖构造函数。存档必须以
 
Note
存档名称应相对于存档根目录,即,它们不应以路径分隔符开头。
Note
如果arcname(或filename,如果未提供arcname)包含一个空字节,则存档中文件的名称将在该空字节处被截断。
在版本 3.6 中进行了更改:在以'r'模式创建的 ZipFile 或关闭的 ZipFile 上调用write()将引发ValueError。以前,提出了RuntimeError。
ZipFile.writestr(* zinfo_or_arcname , data , compress_type = None , compresslevel = None *)
如果给定,* compress_type 会为新条目的构造函数或 zinfo_or_arcname (如果是ZipInfo实例)覆盖为 compression 参数赋予的值。同样,如果指定, compresslevel *将覆盖构造函数。
Note
当将ZipInfo实例作为* zinfo_or_arcname 参数传递时,使用的压缩方法将是给定ZipInfo实例的 compress_type *成员中指定的压缩方法。默认情况下,ZipInfo构造函数将此成员设置为ZIP_STORED。
在版本 3.2 中更改:* compress_type *参数。
在版本 3.6 中进行了更改:在以'r'模式创建的 ZipFile 或关闭的 ZipFile 上调用writestr()将引发ValueError。以前,提出了RuntimeError。
以下数据属性也可用:
ZipFile.filename- ZIP 文件的名称。
 
ZipFile.debug- 要使用的调试输出级别。可以将其设置为
0(默认,无输出)到3(最多输出)。调试信息被写入sys.stdout。 
- 要使用的调试输出级别。可以将其设置为
 ZipFile.comment
Path Objects
at指定此路径在 zip 文件中的位置,例如'dir/file.txt','dir /'或''。默认为空字符串,表示根。
路径对象公开了pathlib.Path个对象的以下Function:
路径对象可使用/运算符遍历。
Path.name- finally路径组件。
 
Path.open( * , ** )- 在当前路径上调用ZipFile.open()。接受与ZipFile.open()相同的参数。
 
Caution
此函数的签名在 Python 3.9 中以不兼容的方式更改。对于将来兼容的版本,请考虑使用第三方 zipp.Path 软件包(3.0 或更高版本)。
Path.iterdir( )- 枚举当前目录的子级。
 
Path.is_dir( )- 如果当前上下文引用目录,则返回
True。 
- 如果当前上下文引用目录,则返回
 Path.is_file( )- 如果当前上下文引用文件,则返回
True。 
- 如果当前上下文引用文件,则返回
 Path.exists( )- 如果当前上下文引用了 zip 文件中的文件或目录,则返回
True。 
- 如果当前上下文引用了 zip 文件中的文件或目录,则返回
 Path.read_text( * , ** )- 以 unicode 文本读取当前文件。位置参数和关键字参数传递给io.TextIOWrapper(上下文所隐含的
buffer除外)。 
- 以 unicode 文本读取当前文件。位置参数和关键字参数传递给io.TextIOWrapper(上下文所隐含的
 Path.read_bytes( )- 以字节为单位读取当前文件。
 
PyZipFile Objects
PyZipFile构造函数的参数与ZipFile构造函数的参数相同,另外一个参数* optimize *。
- 
    
- class * 
zipfile.PyZipFile(* file , mode ='r', compression = ZIP_STORED , allowZip64 = True , optimize = -1 *) 
- 3.2 版中的新Function:* optimize *参数。
 
 - class * 
 
在版本 3.4 中更改:默认情况下启用 ZIP64 扩展。
实例除ZipFile对象之外,还有一种方法:
writepy(* pathname , basename ='', filterfunc = None *)- 搜索文件
*.py并将相应的文件添加到存档中。 
- 搜索文件
 
如果未提供PyZipFile或-1的* optimize *参数,则对应的文件是*.pyc文件,并在必要时进行编译。
如果PyZipFile的* optimize *参数是0,1或2,则仅将具有该优化级别(请参见compile())的文件添加到存档中,并在必要时进行编译。
如果* pathname 是文件,则文件名必须以.py结尾,并且仅在顶层添加(对应的*.pyc)文件(没有路径信息)。如果 pathname *是不以.py结尾的文件,则将引发RuntimeError。如果它是目录,并且该目录不是软件包目录,那么所有文件*.pyc都将添加到顶层。如果该目录是程序包目录,则所有*.pyc都将作为文件路径添加到程序包名称下,如果任何子目录是程序包目录,则所有这些都将按排序 Sequences 递归添加。
basename *仅供内部使用。
filterfunc (如果给定的话)必须是带有单个字符串参数的函数。在将其添加到存档之前,它将pass每个路径(包括每个单独的完整文件路径)传递。如果 filterfunc 返回假值,则不会添加该路径,如果它是目录,则其内容将被忽略。例如,如果我们的测试文件全部位于
test目录中或以字符串test_开头,则可以使用 filterfunc *排除它们:
>>> 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 版中的新Function:* filterfunc *参数。
在版本 3.6.2 中更改:* pathname *参数接受path-like object。
在版本 3.7 中更改:递归对目录条目进行排序。
ZipInfo Objects
ZipInfo类的实例由ZipFile对象的getinfo()和infolist()方法返回。每个对象都存储有关 ZIP 存档的单个成员的信息。
有一种方法可以为文件系统文件创建ZipInfo实例:
- 
    
- classmethod * 
ZipInfo.from_file(* filename , arcname = None ,**,* strict_timestamps = True *) 
- 为文件系统上的文件构造一个ZipInfo实例,以准备将其添加到 zip 文件中。
 
 - classmethod * 
 
- filename *应该是文件系统上文件或目录的路径。
 
如果指定了* arcname ,它将用作存档中的名称。如果未指定 arcname ,则该名称将与 filename *相同,但会删除任何驱动器号和前导路径分隔符。
- strict_timestamps *参数设置为
False时,允许压缩早于 1980-01-01 的文件,但需要将时间戳设置为 1980-01-01.对于高于 2107-12-31 的文件,也会发生类似的行为,时间戳也设置为限制。 
3.6 版的新Function。
在版本 3.6.2 中更改:* filename *参数接受path-like object。
3.8 版中的新Function:* strict_timestamps *仅关键字参数
实例具有以下方法和属性:
ZipInfo.is_dir( )- 如果此存档成员是目录,则返回
True。 
- 如果此存档成员是目录,则返回
 
这使用条目的名称:目录应始终以/结尾。
3.6 版的新Function。
ZipInfo.filename- 存档中文件的名称。
 
ZipInfo.date_time- 最后一次修改存档成员的时间和日期。这是六个值的 Tuples:
 
| Index | Value | 
|---|---|
0 | 
      年(> = 1980) | 
1 | 
      Month (one-based) | 
2 | 
      一个月中的某天(基于 1 天) | 
3 | 
      Hours (zero-based) | 
4 | 
      Minutes (zero-based) | 
5 | 
      Seconds (zero-based) | 
Note
ZIP 文件格式不支持 1980 年之前的时间戳。
ZipInfo.compress_type- 存档成员的压缩类型。
 
ZipInfo.comment- 以bytes对象的形式 Comments 单个存档成员。
 
ZipInfo.extra- 扩展字段数据。 PKZIP 应用说明包含对该bytes对象中包含的数据的内部结构的一些 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 的大小。
 
Command-Line Interface
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
  Command-line options
-l<zipfile>--list<zipfile>- 列出 zipfile 中的文件。
 
-c<zipfile> <source1> ... <sourceN>--create<zipfile> <source1> ... <sourceN>- 从源文件创建 zipfile。
 
-e<zipfile> <output_dir>--extract<zipfile> <output_dir>- 将 zipfile 解压缩到目标目录。
 
-t<zipfile>--test<zipfile>- 测试 zipfile 是否有效。
 
Decompression pitfalls
zipfile 模块中的提取可能由于以下列出的一些陷阱而失败。
来自文件本身
由于密码不正确/ CRC 校验和/ ZIP 格式或不支持的压缩方法/解密,解压缩可能会失败。
文件系统限制
在不同文件系统上的限制可能会导致解压缩失败。例如目录条目中的允许字符,文件名的长度,路径名的长度,单个文件的大小以及文件数等。
Resources limitations
内存或磁盘容量不足会导致解压缩失败。例如,解压缩炸弹(也称为ZIP bomb)应用于 zipfile 库,这可能导致磁盘卷用尽。
Interruption
解压缩过程中的break(例如按 Control-C 或终止解压缩过程)可能会导致存档的解压缩不完全。
提取的默认行为
不知道默认的提取行为会导致意外的减压结果。例如,两次提取相同的归档文件时,它将覆盖文件而无需询问。