You are here:  Home » Python » zipfile使用ZIP档案(5)Python数据压缩和存档(必读进阶Python教程)(参考资料)

ZIP文件格式是常见的归档和压缩标准。此模块提供用于创建,读取,写入,追加和列出ZIP文件的工具。任何高级使用此模块都需要了解格式,如PKZIP应用笔记中所定义。

此模块当前不处理多磁盘ZIP文件。它可以处理使用ZIP64扩展的ZIP文件(即大小超过4 GiB的ZIP文件)。它支持ZIP存档中加密文件的解密,但它目前无法创建加密文件。解密非常慢,因为它是在本机Python而不是C中实现的。

该模块定义了以下项目:

异常zipfile.BadZipFile
错误的ZIP文件引发的错误。

版本3.2中的新功能。

异常zipfile.BadZipfile
别名BadZipFile,与旧版Python兼容。

自3.2版以来已弃用。

异常zipfile.LargeZipFile
ZIP文件需要ZIP64功能但尚未启用时引发的错误。
类 zipfile.ZipFile
用于读写ZIP文件的类。有关构造函数的详细信息,请参阅ZipFile对话部分
类 zipfile.PyZipFile
用于创建包含Python库的ZIP存档的类。
zipfile.ZipInfo文件名= ‘NONAME’ DATE_TIME =(198011000) 
用于表示存档成员信息的类。该类的实例由对象getinfo()infolist() 方法返回ZipFile。该zipfile模块的大多数用户不需要创建这些用户,而只使用该模块创建的用户。filename应该是归档成员的全名,而date_time应该是一个包含六个字段的元组,用于描述上次修改文件的时间; 这些字段在ZipInfo对象中描述 。
zipfile.is_zipfile文件名
返回True如果文件名是基于它的幻数有效的ZIP文件,否则回报False。 filename也可以是文件或类文件对象。

在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应用说明
Phil Katz的ZIP文件格式文档,使用的格式和算法的创建者。
信息ZIP主页
有关Info-ZIP项目的ZIP存档程序和开发库的信息。

ZipFile对象

class zipfile.ZipFilefilemode =’r’compression = ZIP_STOREDallowZip64 = Truecompresslevel = None 
打开ZIP文件,其中file可以是文件(字符串)的路径,类文件对象或类似路径的对象

模式参数应该是'r'读取现有的文件,'w'以截断并写入新文件,'a'追加到现有的文件,或'x'专门创建并写入新文件。如果mode'x'file引用现有文件,FileExistsError则会引发a。如果mode'a'file引用现有的ZIP文件,则会向其中添加其他文件。如果文件未引用ZIP文件,则会将新的ZIP存档附加到该文件。这用于将ZIP存档添加到另一个文件(例如python.exe)。如果 模式'a'并且该文件根本不存在,它被创建。如果mode'r'or 'a',则该文件应该是可搜索的。

压缩是书写时存档,并应使用ZIP压缩方法ZIP_STOREDZIP_DEFLATED, ZIP_BZIP2ZIP_LZMA; 无法识别的值将导致NotImplementedError被提升。如果 ZIP_DEFLATEDZIP_BZIP2或者ZIP_LZMA被指定但相应的模块(zlibbz2lzma)不可用,则RuntimeError上升。默认是ZIP_STORED

如果allowZip64True(默认)zipfile将创建ZIP文件,当zipfile大于4 GiB时使用ZIP64扩展名。如果它将false zipfile在ZIP文件需要ZIP64扩展时引发异常。

compresslevel参数控制文件写入到归档时要使用的压缩级别。使用时ZIP_STOREDZIP_LZMA没有效果。当使用ZIP_DEFLATED整数0通过9接受(参见zlib了解更多信息)。当使用ZIP_BZIP2整数1通过9接受(参见bz2了解更多信息)。

如果该文件与模式创建'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'模式的支持。

在版本3.6中更改:以前,RuntimeError针对无法识别的压缩值引发了平原。

改变在3.6.2版本:文件参数接受路径状物体

在版本3.7中更改:添加compresslevel参数。

ZipFile.close
关闭存档文件。您必须close()在退出程序前致电或不会写入基本记录。
ZipFile.getinfo名字
返回包含ZipInfo存档成员名称信息的对象 。调用getinfo()存档中当前未包含的名称将引发一个KeyError
ZipFile.infolist
返回包含ZipInfo存档的每个成员的对象的列表。如果打开现有存档,则对象与磁盘上实际ZIP文件中的条目的顺序相同。
ZipFile.namelist
按名称返回归档成员列表。
ZipFile.opennamemode =’r’pwd = None*force_zip64 = False 
以二进制文件类对象的形式访问存档成员。 name 可以是归档文件的名称,也可以是ZipInfo 对象。所述模式参数,如果包括的话,必须是'r'(默认值)或'w'。 pwd是用于解密加密的ZIP文件的密码。

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

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

 

随着模式 'r'的类文件对象(ZipExtFile)是只读,并提供了以下方法: read()readline()readlines()seek(), tell()__iter__()__next__()。这些对象可以独立于ZipFile运行。

使用mode='w',返回一个可写文件句柄,它支持该 write()方法。当可写文件句柄打开时,尝试读取或写入ZIP文件中的其他文件将引发 ValueError

写入文件时,如果文件大小事先未知但可能超过2 GiB,则传递force_zip64=True以确保标头格式能够支持大文件。如果事先知道文件大小,请ZipInfo使用file_sizeset 构造一个对象,并将其用作name参数。

注意

open()read()extract()方法可利用一个文件名或ZipInfo对象。在尝试读取包含具有重复名称的成员的ZIP文件时,您将会欣赏这一点。

版本3.6中已更改:已删除支持mode='U'。使用io.TextIOWrapper在读压缩文本文件的通用换行模式。

版本3.6中已更改:open()现在可以使用该mode='w'选项将文件写入存档 。

在版本3.6中更改:调用open()已关闭的ZipFile将引发一个ValueError。以前,RuntimeError有人提出过。

ZipFile.extractmemberpath = Nonepwd = None 
将成员从存档中提取到当前工作目录; 成员 必须是其全名或ZipInfo对象。其文件信息尽可能准确地提取。path指定要提取的其他目录。 member可以是文件名或ZipInfo对象。 pwd是用于加密文件的密码。

返回创建的规范化路径(目录或新文件)。

注意

如果成员文件名是绝对路径,则驱动器/ UNC共享点和前导(后退)斜杠将被剥离,例如:///foo/bar变为 foo/barUnix,并C:\foo\bar变为foo\barWindows。并且".."会删除成员文件名中的所有组件,例如: ../../foo../../ba..r成为foo../ba..r。在Windows非法字符(:<>|"?,并*用下划线代替)( _)。

在版本3.6中更改:调用extract()已关闭的ZipFile将引发一个 ValueError。以前,RuntimeError有人提出过。

改变在3.6.2版本:路径参数接受路径状物体

ZipFile.extractallpath = Nonemembers = Nonepwd = None 
将存档中的所有成员解压缩到当前工作目录。 path 指定要提取的其他目录。 成员是可选的,必须是返回的列表的子集namelist()。 pwd是用于加密文件的密码。

警告

未经事先检查,切勿从不受信任的来源提取档案。文件可能在路径之外创建,例如,具有"/"以两个点开头的绝对文件名或具有两个点的文件名的成员".."。该模块试图阻止这种情况。见extract()注释。

在版本3.6中更改:调用extractall()已关闭的ZipFile将引发一个 ValueError。以前,RuntimeError有人提出过。

改变在3.6.2版本:路径参数接受路径状物体

ZipFile.printdir
打印存档的目录sys.stdout
ZipFile.setpasswordpwd 
pwd设置为默认密码以提取加密文件。
ZipFile.readnamepwd = None 
返回归档中文件的字节。 name是存档中文件的名称或ZipInfo对象。存档必须打开以供阅读或追加。pwd是用于加密文件的密码,如果指定,它将覆盖使用设置的默认密码setpassword()。呼吁 read()对使用比其他压缩方法的ZipFile ZIP_STOREDZIP_DEFLATEDZIP_BZIP2或 ZIP_LZMA将引发NotImplementedError。如果相应的压缩模块不可用,也会引发错误。

在版本3.6中更改:调用read()已关闭的ZipFile将引发一个ValueError。以前,RuntimeError有人提出过。

ZipFile.testzip
读取存档中的所有文件并检查其CRC和文件头。返回第一个坏文件的名称,否则返回None

在版本3.6中更改:调用testzip()已关闭的ZipFile将引发一个 ValueError。以前,RuntimeError有人提出过。

ZipFile.writefilenamearcname = Nonecompress_type = Nonecompresslevel = None 
将名为filename的文件写入存档,为其提供存档名称 arcname(默认情况下,这将与文件名相同,但没有驱动器号,并且删除了前导路径分隔符)。如果给定,则compress_type 会将为压缩参数指定的值覆盖为新条目的构造函数。类似地,如果给定,compresslevel将覆盖构造函数。存档必须以模式打开'w''x''a'

注意

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

注意

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

在版本3.6中更改:调用write()使用模式创建的ZipFile 'r'或关闭的ZipFile将引发一个ValueError。以前,RuntimeError有人提出过。

ZipFile.writestrzinfo_or_arcnamedatacompress_type = Nonecompresslevel = None 
将文件写入存档。内容是数据,可以是一个str或一个bytes实例; 如果是a str,则首先将其编码为UTF-8。zinfo_or_arcname是它将在归档中提供的文件名,或者是ZipInfo实例。如果是实例,则必须至少提供文件名,日期和时间。如果是名称,则将日期和时间设置为当前日期和时间。必须使用模式打开存档'w''x''a'

如果给定,compress_type 会将压缩 参数指定的值覆盖到新条目的构造函数,或者覆盖zinfo_or_arcname(如果它是ZipInfo实例)。类似地,如果给定,compresslevel将覆盖构造函数。

注意

ZipInfo实例作为zinfo_or_arcname参数传递时,使用的压缩方法将是 给定实例的compress_type成员中指定的压缩方法ZipInfo。默认情况下, ZipInfo构造函数将此成员设置为ZIP_STORED

改变在3.2版本:compress_type参数。

在版本3.6中更改:调用writestr()使用模式创建的ZipFile 'r'或关闭的ZipFile将引发一个ValueError。以前,RuntimeError有人提出过。

还提供以下数据属性:

ZipFile.filename
ZIP文件的名称。
ZipFile.debug
要使用的调试输出级别。这可以从0(默认,无输出)到3(最大输出)设置。调试信息被写入 sys.stdout
ZipFile.comment
与ZIP文件关联的注释作为bytes对象。如果为ZipFile使用mode创建的实例分配注释 'w''x'或者'a'它应该不超过65535字节。超过此时间的注释将被截断。

PyZipFile对象

PyZipFile构造函数将相同的参数 ZipFile构造器,以及一个附加参数,优化

class zipfile.PyZipFilefilemode =’r’compression = ZIP_STOREDallowZip64 = Trueoptimize = -1 

新版本3.2:优化参数。

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

除了ZipFile对象之外,实例还有一个方法:

writepypathnamebasename =”filterfunc = None 
搜索文件*.py并将相应的文件添加到存档中。

如果未给出optimize参数,PyZipFile或者-1相应的文件是*.pyc文件,则在必要时进行编译。

如果要将optimize参数设置PyZipFile01或者 2只将具有该优化级别的文件(请参阅参考资料compile())添加到存档中,则必要时进行编译。

如果pathname是文件,则文件名必须以.py,并且只*.pyc在顶层添加(相应)文件(无路径信息)。如果路径是不是结束一个文件 .py,一个RuntimeError将提高。如果它是目录,并且该目录不是包目录,则所有文件 *.pyc都添加在顶层。如果目录是包目录,则所有目录*.pyc都是作为文件路径添加在包名称下,如果任何子目录是包目录,则所有这些都按排序顺序递归添加。

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参数。

改变在3.6.2版本:路径参数接受路径状物体

版本3.7中已更改:递归对目录条目进行排序。

ZipInfo对象

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

有一种类方法可以ZipInfo为文件系统文件创建一个实例:

classmethod ZipInfo.from_filefilenamearcname = None 
ZipInfo在文件系统上构造文件的实例,准备将其添加到zip文件中。

filename应该是文件系统上文件或目录的路径。

如果指定了arcname,则将其用作存档中的名称。如果未指定arcname,则名称将与filename相同,但删除了任何驱动器号和前导路径分隔符。

版本3.6中的新功能。

改变在3.6.2版本:文件名参数接受路径状物体

实例具有以下方法和属性:

ZipInfo.is_dir
True如果此归档成员是目录,则返回。

这使用条目的名称:目录应始终以/

版本3.6中的新功能。

ZipInfo.filename
存档中文件的名称。
ZipInfo.date_time
上次修改存档成员的时间和日期。这是六个值的元组:

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

注意

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

ZipInfo.compress_type
存档成员的压缩类型。
ZipInfo.comment
将单个归档成员注释为bytes对象。
ZipInfo.extra
扩展现场数据。在PKZIP应用笔记包含包含在该数据的内部结构的一些评论 bytes的对象。
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
未压缩文件的大小。

命令行界面

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

 

命令行选项

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