13.5. zipfile — ZIP 归档访问

源代码: Lib / zipfile.py

ZIP文件格式是一种常见的归档和压缩标准.本模块提供了工具来创建、 读、 写、 追加,列出一个 ZIP 文件。此模块的任何高级使用将需要了解如PKZIP应用笔记中定义的格式。

本模块不能目前处理多磁盘 ZIP 文件。它可以处理 ZIP 文件,使用 ZIP64 扩展 (也就是那些在大小超过 4 GiB 的 ZIP 文件)。它支持加密ZIP 存档文件的解密,但它当前不能创建加密的文件。解密是极其缓慢的当它在本机 Python,而不是 C.中实现.

模块定义以下项目:

exception zipfile.BadZipFile

错误ZIP文件引发的错误。

版本3.2中的新功能。

exception zipfile.BadZipfile

为了与旧的Python版本兼容,BadZipFile的别名。

自3.2版起已弃用。

exception zipfile.LargeZipFile

ZIP文件需要ZIP64功能但尚未启用时引发的错误。

class zipfile. ZipFile

用于读取和写入ZIP文件的类。有关构造函数的详细信息,请参见ZipFile Objects一节。

class zipfile. PyZipFile

用于创建包含Python库的ZIP存档的类。

class zipfile.ZipInfo(filename='NoName', date_time=(1980, 1, 1, 0, 0, 0))

用于表示有关归档成员的信息的类。此类的实例由ZipFile对象的getinfo()infolist()方法返回。zipfile模块的大多数用户不需要创建这些模块,而只使用由此模块创建的模块。filename应为存档成员的全名,date_time应为包含六个字段的元组,这六个字段描述文件最后一次修改的时间;这些字段在ZipInfo Objects部分中描述。

zipfile.is_zipfile(filename)

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

在3.1版中已更改:支持文件和类似文件的对象。

zipfile.ZIP_STORED

未压缩的归档成员的数字常量。

zipfile.ZIP_DEFLATED

常用ZIP压缩方法的数字常量。这需要zlib模块。

zipfile.ZIP_BZIP2

BZIP2压缩方法的数字常量。这需要bz2模块。

版本3.3中的新功能。

zipfile.ZIP_LZMA

LZMA压缩方法的数字常量。这需要lzma模块。

版本3.3中的新功能。

注意

ZIP文件格式规范包括自2001年以来对bzip2压缩的支持,以及自2006年以来的LZMA压缩。但是,一些工具(包括旧的Python版本)不支持这些压缩方法,可能会拒绝完全处理ZIP文件,或无法提取单个文件。

也可以看看

PKZIP应用笔记
关于ZIP文件格式的文档由Phil Katz,使用的格式和算法的创建者。
Info-ZIP主页
有关Info-ZIP项目的ZIP归档程序和开发库的信息。

13.5.1. ZipFile Objects

class zipfile.ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True)

打开ZIP文件,其中文件可以是文件(字符串)或类似文件的对象的路径。模式参数应为'r'以读取现有文件'w'以截断并写入新文件'a'以附加到现有文件,或'x'以专门创建和写入新文件。如果模式'x'file变量指现有文件,则会引发FileExistsError如果模式'a'文件指现有的ZIP文件,则会向其添加其他文件。如果文件不引用ZIP文件,则会将新的ZIP存档附加到该文件。这是为了将ZIP存档添加到另一个文件(例如python.exe)。如果模式a,且文件根本不存在,则会创建该文件。如果模式ra,则文件应为可搜索的。压缩是在撰写封存时使用的ZIP压缩方法,应为ZIP_STOREDZIP_DEFLATEDZIP_BZIP2 ZIP_LZMA;无法识别的值将引起RuntimeErrorIf ZIP_DEFLATED, ZIP_BZIP2 or ZIP_LZMA is specified but the corresponding module (zlib, bz2 or lzma) is not available, RuntimeError is also raised. 默认值为ZIP_STORED如果allowZip64True(默认值)zip文件将创建ZIP文件,当zip文件大于2 GiB时使用ZIP64扩展。如果为false,则当ZIP文件需要ZIP64扩展时,zipfile将引发异常。

如果使用模式'w''x''a'创建文件,然后按closed将任何文件添加到归档中,空归档的相应ZIP结构将被写入文件。

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

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

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

在版本3.3中已更改:添加了对bzip2lzma压缩的支持。

在版本3.4中更改: ZIP64扩展名默认情况下已启用。

在3.5版本中进行了更改:添加了对写入不可搜索流的支持。添加了对'x'模式的支持。

ZipFile.close()

关闭归档文件。您必须在退出程序之前调用close(),否则不会写入基本记录。

ZipFile.getinfo(name)

返回具有有关归档成员名称的信息的ZipInfo对象。为当前未包含在归档中的名称调用getinfo()将引发KeyError

ZipFile.infolist()

返回包含归档的每个成员的ZipInfo对象的列表。如果打开了现有归档,则对象与磁盘上实际ZIP文件中的条目的顺序相同。

ZipFile.namelist()

按名称返回归档成员的列表。

ZipFile.open(name, mode='r', pwd=None)

从归档中提取成员作为文件状对象(ZipExtFile)。名称是档案中文件的名称,或ZipInfo对象。The mode parameter, if included, must be one of the following: 'r' (the default), 'U', or 'rU'. 选择'U''rU'将在只读对象中启用universal newlines支持。pwd是用于加密文件的密码。在封闭的ZipFile上调用open()会引发RuntimeError

open()也是一个上下文管理器,因此支持with语句:

with ZipFile('spam.zip') as myzip:
    with myzip.open('eggs.txt') as myfile:
        print(myfile.read())

注意

类文件对象是只读的并提供以下方法:read()readline()readlines()__iter__()__next__()

注意

open()返回的对象可以独立于ZipFile操作。

注意

open()read()extract()方法可以采用文件名或ZipInfo当您尝试读取包含重复名称的成员的ZIP文件时,您将会感激此。

从版本3.4开始弃用,将在版本3.6中删除: 'U''rU'模式。使用io.TextIOWrapperuniversal newlines模式下读取压缩文本文件。

ZipFile.extract(member, path=None, pwd=None)

将成员从归档提取到当前工作目录; 成员必须是其全名或ZipInfo对象。其文件信息尽可能精确地提取。路径指定要提取到的不同目录。成员可以是文件名或ZipInfo对象。pwd是用于加密文件的密码。

返回已创建的标准化路径(目录或新文件)。

注意

如果成员文件名是绝对路径,则驱动器/ UNC共享点和前导(后)斜杠将被去除。///foo/bar在Unix上变为foo/bar,并且C:\foo\bar变为foo\bar并且将删除成员文件名中的所有".."组件。: ../../foo../../ba..r becomes foo../ba..r. On Windows illegal characters (:, <, >, |, ", ?, and *) replaced by underscore (_).

ZipFile.extractall(path=None, members=None, pwd=None)

将归档中的所有成员解压缩到当前工作目录。路径指定要提取到的不同目录。成员是可选的,并且必须是由namelist()返回的列表的子集。pwd是用于加密文件的密码。

警告

切勿在未经预先检查的情况下从不可信来源中提取存档。可能在路径之外创建文件,例如具有以"/"开头的绝对文件名的成员或具有两个点".."的文件名。此模块尝试阻止。请参阅extract()注意。

ZipFile.printdir()

将归档的目录打印到sys.stdout

ZipFile.setpassword(pwd)

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

ZipFile.read(name, pwd=None)

返回归档中文件名称的字节。名称是档案中文件的名称,或ZipInfo对象。归档必须打开以进行读取或追加。pwd是用于加密文件的密码,如果指定,它将覆盖使用setpassword()设置的默认密码。在封闭的ZipFile上调用read()会引发RuntimeErrorCalling read() on a ZipFile that uses a compression method other than ZIP_STORED, ZIP_DEFLATED, ZIP_BZIP2 or ZIP_LZMA will raise a NotImplementedError. 如果相应的压缩模块不可用,也会出现错误。

ZipFile.testzip()

读取归档中的所有文件,并检查其CRC和文件头。返回第一个坏文件的名称,否则返回None在封闭的ZipFile上调用testzip()会引发RuntimeError

ZipFile.write(filename, arcname=None, compress_type=None)

将名为filename的文件写入归档文件,给它归档名称arcname(默认情况下,这将与filename相同,驱动器盘符,并删除了导向路径分隔符)。如果给定,compress_type会覆盖为新条目的构造函数为压缩参数指定的值。The archive must be open with mode 'w', 'x' or 'a' – calling write() on a ZipFile created with mode 'r' will raise a RuntimeError. 在封闭的ZipFile上调用write()会引发RuntimeError

注意

ZIP文件没有正式的文件名编码。如果您有unicode文件名,则必须在将它们传递到write()之前将它们转换为所需编码中的字节字符串。WinZip将所有文件名解释为在CP437中编码的,也称为DOS Latin。

注意

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

注意

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

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

将字符串数据写入归档; zinfo_or_arcname是档案中的档案名称,或是ZipInfo实例。如果它是一个实例,至少必须给出文件名,日期和时间。如果是名称,则日期和时间设置为当前日期和时间。The archive must be opened with mode 'w', 'x' or 'a' – calling writestr() on a ZipFile created with mode 'r' will raise a RuntimeError. 在封闭的ZipFile上调用writestr()会引发RuntimeError

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

注意

When passing a ZipInfo instance as the zinfo_or_arcname parameter, the compression method used will be that specified in the compress_type member of the given ZipInfo instance. 默认情况下,ZipInfo构造函数将此成员设置为ZIP_STORED

在版本3.2中更改: compress_type参数。

还提供以下数据属性:

ZipFile.debug

要使用的调试输出的级别。这可以从0(默认值,无输出)设置为3(最大输出)。调试信息写入sys.stdout

ZipFile.comment

与ZIP文件相关联的注释文本。如果为使用模式'w''x''a'创建的ZipFile ,这应该是不超过65535字节的字符串。当调用close()时,长于此值的注释将在写入的归档中被截断。

13.5.2. PyZipFile Objects

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并将相应的文件添加到存档。

如果未给出PyZipFileoptimize参数或-1,则相应的文件为*.pyc文件,如有必要,进行编译。

If the optimize parameter to PyZipFile was 0, 1 or 2, only files with that optimization level (see compile()) are added to the archive, compiling if necessary.

如果pathname是文件,则文件名必须以.py结尾,并且只添加(对应的*.py[co]如果路径名是不以.py结尾的文件,则会引发RuntimeError如果它是一个目录,并且该目录不是包目录,则在顶层添加所有文件*.py[co]如果目录是包目录,则所有*.py[co]作为文件路径添加到包名称下,如果任何子目录是包目录,则所有这些都是递归添加的。

basename仅供内部使用。

filterfunc,如果给定,必须是一个单个字符串参数的函数。它将在添加到归档文件之前传递每个路径(包括每个单独的完整文件路径)。如果filterfunc返回false值,则不会添加路径,如果它是目录,则其内容将被忽略。例如,如果我们的测试文件都在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中的新功能: filterfunc参数。

13.5.3. ZipInfo Objects

ZipInfo类的实例由ZipFile对象的getinfo()infolist()方法返回。每个对象存储有关ZIP归档的单个成员的信息。

实例具有以下属性:

ZipInfo.filename

归档中的文件的名称。

ZipInfo.date_time

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

指数
0年(> = 1980)
1月(从1个月)
2日(月份)
3小时(从零开始)
4分钟(从零开始)
5秒(从零开始)

注意

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

ZipInfo.compress_type

归档成员的压缩类型。

ZipInfo.comment

个人档案成员的注释。

ZipInfo.extra

扩展字段数据。PKZIP应用程序注释包含对此字符串中包含的数据的内部结构的一些注释。

ZipInfo.create_system

创建ZIP存档的系统。

ZipInfo.create_version

PKZIP版本创建ZIP存档。

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

未压缩文件的大小。