zipfile --- 使用ZIP存檔?
源代碼: Lib/zipfile.py
ZIP 文件格式是一個(gè)常用的歸檔與壓縮標(biāo)準(zhǔn)。 這個(gè)模塊提供了創(chuàng)建、讀取、寫入、添加及列出 ZIP 文件的工具。 任何對(duì)此模塊的進(jìn)階使用都將需要理解此格式,其定義參見 PKZIP 應(yīng)用程序筆記。
此模塊目前不能處理分卷 ZIP 文件。它可以處理使用 ZIP64 擴(kuò)展(超過 4 GB 的 ZIP 文件)的 ZIP 文件。它支持解密 ZIP 歸檔中的加密文件,但是目前不能創(chuàng)建一個(gè)加密的文件。解密非常慢,因?yàn)樗鞘褂迷?Python 而不是 C 實(shí)現(xiàn)的。
這個(gè)模塊定義了以下內(nèi)容:
-
exception
zipfile.BadZipFile? 為損壞的 ZIP 文件拋出的錯(cuò)誤。
3.2 新版功能.
-
exception
zipfile.BadZipfile? BadZipFile的別名,與舊版本 Python 保持兼容性。3.2 版后已移除.
-
exception
zipfile.LargeZipFile? 當(dāng) ZIP 文件需要 ZIP64 功能但是未啟用時(shí)會(huì)拋出此錯(cuò)誤。
-
class
zipfile.ZipFile 用于讀寫 ZIP 文件的類。 欲了解構(gòu)造函數(shù)的描述,參閱段落 ZipFile 對(duì)象。
-
class
zipfile.PyZipFile 用于創(chuàng)建包含 Python 庫的 ZIP 歸檔的類。
-
class
zipfile.ZipInfo(filename='NoName', date_time=(1980, 1, 1, 0, 0, 0))? 用于表示檔案內(nèi)一個(gè)成員信息的類。 此類的實(shí)例會(huì)由
ZipFile對(duì)象的getinfo()和infolist()方法返回。 大多數(shù)zipfile模塊的用戶都不必創(chuàng)建它們,只需使用此模塊所創(chuàng)建的實(shí)例。 filename 應(yīng)當(dāng)是檔案成員的全名,date_time 應(yīng)當(dāng)是包含六個(gè)字段的描述最近修改時(shí)間的元組;這些字段的描述請(qǐng)參閱 ZipInfo 對(duì)象。
-
zipfile.is_zipfile(filename)? 根據(jù)文件的 Magic Number,如果 filename 是一個(gè)有效的 ZIP 文件則返回
True,否則返回False。 filename 也可能是一個(gè)文件或類文件對(duì)象。在 3.1 版更改: 支持文件或類文件對(duì)象。
-
zipfile.ZIP_STORED? 未被壓縮的歸檔成員的數(shù)字常數(shù)。
-
zipfile.ZIP_LZMA? LZMA 壓縮方法的數(shù)字常數(shù)。需要
lzma模塊。3.3 新版功能.
注解
ZIP 文件格式規(guī)范包括自 2001 年以來對(duì) bzip2 壓縮的支持,以及自 2006 年以來對(duì) LZMA 壓縮的支持。但是,一些工具(包括較舊的 Python 版本)不支持這些壓縮方法,并且可能拒絕完全處理 ZIP 文件,或者無法提取單個(gè)文件。
參見
- PKZIP 應(yīng)用程序筆記
Phil Katz 編寫的 ZIP 文件格式文檔,此格式和使用的算法的創(chuàng)建者。
- Info-ZIP 主頁
有關(guān) Info-ZIP 項(xiàng)目的 ZIP 存檔程序和開發(fā)庫的信息。
ZipFile 對(duì)象?
-
class
zipfile.ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, compresslevel=None)? 打開一個(gè) ZIP 文件,file 為一個(gè)指向文件的路徑(字符串),一個(gè)類文件對(duì)象或者一個(gè) path-like object。
形參 mode 應(yīng)當(dāng)為
'r'來讀取一個(gè)存在的文件,'w'來截?cái)嗖懭胄碌奈募?'a'來添加到一個(gè)存在的文件,或者'x'來僅新建并寫入新的文件。如果 mode 為'x'并且 file 指向已經(jīng)存在的文件,則拋出FileExistsError。如果 mode 為'a'且 file 為已存在的文件,則格外的文件將被加入。如果 file 不指向 ZIP 文件,之后一個(gè)新的 ZIP 歸檔將被追加為此文件。這是為了將 ZIP 歸檔添加到另一個(gè)文件(例如python.exe)。如果 mode 為'a'并且文件不存在, 則會(huì)新建。如果 mode 為'r'或'a', 則文件應(yīng)當(dāng)可定位。compression 是在寫入歸檔時(shí)要使用的 ZIP 壓縮方法,應(yīng)為
ZIP_STORED,ZIP_DEFLATED,ZIP_BZIP2或ZIP_LZMA;不可識(shí)別的值將導(dǎo)致引發(fā)NotImplementedError。 如果指定了ZIP_DEFLATED,ZIP_BZIP2或ZIP_LZMA但相應(yīng)的模塊 (zlib,bz2或lzma) 不可用,則會(huì)引發(fā)RuntimeError。 默認(rèn)值為ZIP_STORED。如果 allowZip64 為
True(默認(rèn)值) 則當(dāng) zipfile 大于 4 GiB 時(shí) zipfile 將創(chuàng)建使用 ZIP64 擴(kuò)展的 ZIP 文件。 如果該參數(shù)為false則當(dāng) ZIP 文件需要 ZIP64 擴(kuò)展時(shí)zipfile將引發(fā)異常。compresslevel 形參控制在將文件寫入歸檔時(shí)要使用的壓縮等級(jí)。 當(dāng)使用
ZIP_STORED或ZIP_LZMA時(shí)無壓縮效果。 當(dāng)使用ZIP_DEFLATED時(shí)接受整數(shù)0至9(更多信息參見zlib)。 當(dāng)使用ZIP_BZIP2時(shí)接受整數(shù)1至9(更多信息參見bz2)。如果創(chuàng)建文件時(shí)使用
'w','x'或'a'模式并且未向歸檔添加任何文件就執(zhí)行了closed,則會(huì)將適當(dāng)?shù)目諝w檔 ZIP 結(jié)構(gòu)寫入文件。ZipFile 也是一個(gè)上下文管理器,因此支持
with語句。 在這個(gè)示例中,myzip 將在with語句塊執(zhí)行完成之后被關(guān)閉 --- 即使是發(fā)生了異常:with ZipFile('spam.zip', 'w') as myzip: myzip.write('eggs.txt')
3.2 新版功能: 添加了將
ZipFile用作上下文管理員的功能。在 3.4 版更改: 默認(rèn)啟用 ZIP64 擴(kuò)展。
在 3.5 版更改: 添加了對(duì)不可查找數(shù)據(jù)流的支持。 并添加了對(duì)
'x'模式的支持。在 3.6 版更改: 在此之前,對(duì)于不可識(shí)別的壓縮值將引發(fā)普通的
RuntimeError。在 3.6.2 版更改: file 形參接受一個(gè) path-like object。
在 3.7 版更改: 添加了 compresslevel 形參。
-
ZipFile.getinfo(name)? 返回一個(gè)
ZipInfo對(duì)象,其中包含有關(guān)歸檔成員 name 的信息。 針對(duì)一個(gè)目前并不包含于歸檔中的名稱調(diào)用getinfo()將會(huì)引發(fā)KeyError。
-
ZipFile.infolist()? 返回一個(gè)列表,其中包含每個(gè)歸檔成員的
ZipInfo對(duì)象。 如果是打開一個(gè)現(xiàn)有歸檔則這些對(duì)象的排列順序與它們對(duì)應(yīng)條目在磁盤上的實(shí)際 ZIP 文件中的順序一致。
-
ZipFile.namelist()? 返回按名稱排序的歸檔成員列表。
-
ZipFile.open(name, mode='r', pwd=None, *, force_zip64=False)? 以二進(jìn)制文件類對(duì)象的形式訪問一個(gè)歸檔成員。 name 可以是歸檔內(nèi)某個(gè)文件的名稱也可以是某個(gè)
ZipInfo對(duì)象。 如果包含了 mode 形參,則它必須為'r'(默認(rèn)值) 或'w'。 pwd 為用于解密已加密 ZIP 文件的密碼。open()也是一個(gè)上下文管理器,因此支持with語句:with ZipFile('spam.zip') as myzip: with myzip.open('eggs.txt') as myfile: print(myfile.read())
當(dāng) mode 為
'r'時(shí)文件類對(duì)象 (ZipExtFile) 將為只讀并且提供下列方法:read(),readline(),readlines(),seek(),tell(),__iter__(),__next__()。 這些對(duì)象可獨(dú)立于 ZipFile 進(jìn)行操作。如果
mode='w'則返回一個(gè)可寫入的文件句柄,它將支持write()方法。 當(dāng)一個(gè)可寫入的文件句柄被打開時(shí),嘗試讀寫 ZIP 文件中的其他文件將會(huì)引發(fā)ValueError。當(dāng)寫入一個(gè)文件時(shí),如果文件大小不能預(yù)先確定但是可能超過 2 GiB,可傳入
force_zip64=True以確保標(biāo)頭格式能夠支持超大文件。 如果文件大小可以預(yù)先確定,則在構(gòu)造ZipInfo對(duì)象時(shí)應(yīng)設(shè)置file_size,并將其用作 name 形參。注解
open(),read()和extract()方法可接受文件名或ZipInfo對(duì)象。 當(dāng)嘗試讀取一個(gè)包含重復(fù)名稱成員的 ZIP 文件時(shí)你將發(fā)現(xiàn)此功能很有好處。在 3.6 版更改: 移除了對(duì)
mode='U'的支持。 請(qǐng)使用io.TextIOWrapper以在 universal newlines 模式中讀取已壓縮的文本文件。在 3.6 版更改:
open()現(xiàn)在可以被用來配合mode='w'選項(xiàng)來將文件寫入歸檔。在 3.6 版更改: 在已關(guān)閉的 ZipFile 上調(diào)用
open()將引發(fā)ValueError。 在之前的版本中則會(huì)引發(fā)RuntimeError。
-
ZipFile.extract(member, path=None, pwd=None)? 從歸檔中提取出一個(gè)成員放入當(dāng)前工作目錄;member 必須為成員的完整名稱或
ZipInfo對(duì)象。 成員的文件信息會(huì)盡可能精確地被提取。 path 指定一個(gè)要提取到的不同目錄。 member 可以是一個(gè)文件名或ZipInfo對(duì)象。 pwd 是用于解密文件的密碼。返回所創(chuàng)建的經(jīng)正規(guī)化的路徑(對(duì)應(yīng)于目錄或新文件)。
注解
如果一個(gè)成員文件名為絕對(duì)路徑,則將去掉驅(qū)動(dòng)器/UNC共享點(diǎn)和前導(dǎo)的(反)斜杠,例如:
///foo/bar在 Unix 上將變?yōu)?foo/bar,而C:\foo\bar在 Windows 上將變?yōu)?foo\bar。 并且一個(gè)成員文件名中的所有".."都將被移除,例如:../../foo../../ba..r將變?yōu)?foo../ba..r。 在 Windows 上非法字符 (:,<,>,|,",?, and*) 會(huì)被替換為下劃線 (_)。在 3.6 版更改: 在已關(guān)閉的 ZipFile 上調(diào)用
extract()將引發(fā)ValueError。 在之前的版本中則將引發(fā)RuntimeError。在 3.6.2 版更改: path 形參接受一個(gè) path-like object。
-
ZipFile.extractall(path=None, members=None, pwd=None)? 從歸檔中提取出所有成員放入當(dāng)前工作目錄。 path 指定一個(gè)要提取到的不同目錄。 members 為可選項(xiàng)且必須為
namelist()所返回列表的一個(gè)子集。 pwd 是用于解密文件的密碼。警告
絕不要未經(jīng)預(yù)先檢驗(yàn)就從不可靠的源中提取歸檔文件。 這樣有可能在 path 之外創(chuàng)建文件,例如某些成員具有以
"/"開始的文件名或帶有兩個(gè)點(diǎn)號(hào)".."的文件名。 此模塊會(huì)嘗試防止這種情況。 參見extract()的注釋。在 3.6 版更改: 在已關(guān)閉的 ZipFile 上調(diào)用
extractall()將引發(fā)ValueError。 在之前的版本中則將引發(fā)RuntimeError。在 3.6.2 版更改: path 形參接受一個(gè) path-like object。
-
ZipFile.printdir()? 將歸檔的目錄表打印到
sys.stdout。
-
ZipFile.setpassword(pwd)? 設(shè)置 pwd 為用于提取已加密文件的默認(rèn)密碼。
-
ZipFile.read(name, pwd=None)? 返回歸檔中文件 name 的字節(jié)數(shù)據(jù)。 name 是歸檔中文件的名稱,或是一個(gè)
ZipInfo對(duì)象。 歸檔必須以讀取或追加方式打開。 pwd 為用于已加密文件的密碼,并且如果指定該參數(shù)則它將覆蓋通過setpassword()設(shè)置的默認(rèn)密碼。 on a ZipFile that uses a compression method 在使用ZIP_STORED,ZIP_DEFLATED,ZIP_BZIP2或ZIP_LZMA以外的壓縮方法的 ZipFile 上調(diào)用read()將引發(fā)NotImplementedError。 如果相應(yīng)的壓縮模塊不可用也會(huì)引發(fā)錯(cuò)誤。在 3.6 版更改: 在已關(guān)閉的 ZipFile 上調(diào)用
read()將引發(fā)ValueError。 在之前的版本中則會(huì)引發(fā)RuntimeError.
-
ZipFile.testzip()? 讀取歸檔中的所有文件并檢查它們的 CRC 和文件頭。 返回第一個(gè)已損壞文件的名稱,在其他情況下則返回
None。在 3.6 版更改: 在已關(guān)閉的 ZipFile 上調(diào)用
testzip()將引發(fā)ValueError。 在之前的版本中則將引發(fā)RuntimeError。
-
ZipFile.write(filename, arcname=None, compress_type=None, compresslevel=None)? 將名為 filename 的文件寫入歸檔,給予的歸檔名為 arcname (默認(rèn)情況下將與 filename 一致,但是不帶驅(qū)動(dòng)器盤符并會(huì)移除開頭的路徑分隔符)。 compress_type 如果給出,它將覆蓋作為構(gòu)造器 compression 形參對(duì)于新條目所給出的值。 類似地,compresslevel 如果給出也將覆蓋構(gòu)造器。 歸檔必須使用
'w','x'或'a'模式打開。注解
歸檔名稱應(yīng)當(dāng)是基于歸檔根目錄的相對(duì)路徑,也就是說,它們不應(yīng)以路徑分隔符開頭。
注解
如果
arcname(或filename,如果arcname未給出) 包含一個(gè)空字節(jié),則歸檔中該文件的名稱將在空字節(jié)位置被截?cái)唷?/p>在 3.6 版更改: 在使用
'r'模式創(chuàng)建的 ZipFile 或已關(guān)閉的 ZipFile 上調(diào)用write()將引發(fā)ValueError。 在之前的版本中則會(huì)引發(fā)RuntimeError。
-
ZipFile.writestr(zinfo_or_arcname, data, compress_type=None, compresslevel=None)? 將一個(gè)文件寫入歸檔。 內(nèi)容為 data,它可以是一個(gè)
str或bytes的實(shí)例;如果是str,則會(huì)先使用 UTF-8 進(jìn)行編碼。 zinfo_or_arcname 可以是它在歸檔中將被給予的名稱,或者是ZipInfo的實(shí)例。 如果它是一個(gè)實(shí)例,則至少必須給定文件名、日期和時(shí)間。 如果它是一個(gè)名稱,則日期和時(shí)間會(huì)被設(shè)為當(dāng)前日期和時(shí)間。 歸檔必須以'w','x'或'a'模式打開。如果給定了 compress_type,它將會(huì)覆蓋作為新條目構(gòu)造器的 compression 形參或在 zinfo_or_arcname (如果是一個(gè)
ZipInfo實(shí)例) 中所給出的值。 類似地,如果給定了 compresslevel,它將會(huì)覆蓋構(gòu)造器。注解
當(dāng)傳入一個(gè)
ZipInfo實(shí)例作為 zinfo_or_arcname 形參時(shí),所使用的壓縮方法將為在給定的ZipInfo實(shí)例的 compress_type 成員中指定的方法。 默認(rèn)情況下,ZipInfo構(gòu)造器將將此成員設(shè)為ZIP_STORED。在 3.2 版更改: compress_type 參數(shù)。
在 3.6 版更改: 在使用
'r'模式創(chuàng)建的 ZipFile 或已關(guān)閉的 ZipFile 上調(diào)用writestr()將引發(fā)ValueError。 在之前的版本中則會(huì)引發(fā)RuntimeError。
以下數(shù)據(jù)屬性也是可用的:
-
ZipFile.filename? ZIP 文件的名稱。
-
ZipFile.debug? 要使用的調(diào)試輸出等級(jí)。 這可以設(shè)為從
0(默認(rèn)無輸出) 到3(最多輸出) 的值。 調(diào)試信息會(huì)被寫入sys.stdout。
PyZipFile 對(duì)象?
PyZipFile 構(gòu)造器接受與 ZipFile 構(gòu)造器相同的形參,以及一個(gè)額外的形參 optimize。
-
class
zipfile.PyZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, optimize=-1)? 3.2 新版功能: optimize 形參。
在 3.4 版更改: 默認(rèn)啟用 ZIP64 擴(kuò)展。
實(shí)例在
ZipFile對(duì)象所具有的方法以外還附加了一個(gè)方法:-
writepy(pathname, basename='', filterfunc=None)? 查找
*.py文件并將相應(yīng)的文件添加到歸檔。如果
PyZipFile的 optimize 形參未給定或?yàn)?-1,則相應(yīng)的文件為*.pyc文件,并在必要時(shí)進(jìn)行編譯。如果
PyZipFile的 optimize 形參為0,1或2,則限具有相應(yīng)優(yōu)化級(jí)別 (參見compile()) 的文件會(huì)被添加到歸檔,并在必要時(shí)進(jìn)行編譯。如果 pathname 是文件,則文件名必須以
.py為后綴,并且只有 (相應(yīng)的*.pyc) 文件會(huì)被添加到最高層級(jí)(不帶路徑信息)。 如果 pathname 不是以.py為后綴的文件,則將引發(fā)RuntimeError。 如果它是目錄,并且該目錄不是一個(gè)包目錄,則所有的*.pyc文件會(huì)被添加到最高層級(jí)。 如果目錄是一個(gè)包目錄,則所有的*.pyc會(huì)被添加到包名所表示的文件路徑下,并且如果有任何子目錄為包目錄,則會(huì)以排好的順序遞歸地添加這些目錄。basename 僅限在內(nèi)部使用。
如果給定 filterfunc,則它必須是一個(gè)接受單個(gè)字符串參數(shù)的函數(shù)。 在將其添加到歸檔之前它將被傳入每個(gè)路徑(包括每個(gè)單獨(dú)的完整路徑)。 如果 filterfunc 返回假值,則路徑將不會(huì)被添加,而如果它是一個(gè)目錄則其內(nèi)容將被忽略。 例如,如果我們的測試文件全都位于
test目錄或以字符串test_打頭,則我們可以使用一個(gè) 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()方法會(huì)產(chǎn)生帶有這樣一些文件名的歸檔: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 版更改: pathname 形參接受一個(gè) path-like object。
在 3.7 版更改: 遞歸排序目錄條目。
-
ZipInfo 對(duì)象?
ZipInfo 類的實(shí)例會(huì)通過 getinfo() 和 ZipFile 對(duì)象的 infolist() 方法返回。 每個(gè)對(duì)象將存儲(chǔ)關(guān)于 ZIP 歸檔的一個(gè)成員的信息。
有一個(gè)類方法可以為文件系統(tǒng)文件創(chuàng)建 ZipInfo 實(shí)例:
-
classmethod
ZipInfo.from_file(filename, arcname=None)? 為文件系統(tǒng)中的文件構(gòu)造一個(gè)
ZipInfo實(shí)例,并準(zhǔn)備將其添加到一個(gè) zip 文件。filename 應(yīng)為文件系統(tǒng)中某個(gè)文件或目錄的路徑。
如果指定了 arcname,它會(huì)被用作歸檔中的名稱。 如果未指定 arcname,則所用名稱與 filename 相同,但將去除任何驅(qū)動(dòng)器盤符和打頭的路徑分隔符。
3.6 新版功能.
在 3.6.2 版更改: filename 形參接受一個(gè) path-like object。
實(shí)例具有下列方法和屬性:
-
ZipInfo.is_dir()? 如果此歸檔成員是一個(gè)目錄則返回
True。這會(huì)使用條目的名稱:目錄應(yīng)當(dāng)總是以
/結(jié)尾。3.6 新版功能.
-
ZipInfo.filename? 歸檔中的文件名稱。
-
ZipInfo.date_time? 上次修改存檔成員的時(shí)間和日期。這是六個(gè)值的元組:
索引
值
0Year (>= 1980)
1月(1為基數(shù))
2月份中的日期(1為基數(shù))
3小時(shí)(0為基數(shù))
4分鐘(0為基數(shù))
5秒(0為基數(shù))
注解
ZIP文件格式不支持1980年以前的時(shí)間戳。
-
ZipInfo.compress_type? 歸檔成員的壓縮類型。
-
ZipInfo.extra? 擴(kuò)展字段數(shù)據(jù)。 PKZIP Application Note 包含一些保存于該
bytes對(duì)象中的內(nèi)部結(jié)構(gòu)的注釋。
-
ZipInfo.create_system? 創(chuàng)建 ZIP 歸檔所用的系統(tǒng)。
-
ZipInfo.create_version? 創(chuàng)建 ZIP 歸檔所用的 PKZIP 版本。
-
ZipInfo.extract_version? 需要用來提取歸檔的 PKZIP 版本。
-
ZipInfo.reserved? 必須為零。
-
ZipInfo.flag_bits? ZIP 標(biāo)志位。
-
ZipInfo.volume? 文件中的分卷號(hào)。
-
ZipInfo.internal_attr? 內(nèi)部屬性。
-
ZipInfo.external_attr? 外部文件屬性。
-
ZipInfo.header_offset? 文件頭的字節(jié)偏移量。
-
ZipInfo.CRC? 未壓縮文件的 CRC-32。
-
ZipInfo.compress_size? 已壓縮數(shù)據(jù)的大小。
-
ZipInfo.file_size? 未壓縮文件的大小。
命令行界面?
zipfile 模塊提供了簡單的命令行接口用于與 ZIP 歸檔的交互。
如果你想要?jiǎng)?chuàng)建一個(gè)新的 ZIP 歸檔,請(qǐng)?jiān)?-c 選項(xiàng)后指定其名稱然后列出應(yīng)當(dāng)被包含的文件名:
$ python -m zipfile -c monty.zip spam.txt eggs.txt
傳入一個(gè)目錄也是可接受的:
$ python -m zipfile -c monty.zip life-of-brian_1979/
如果你想要將一個(gè) ZIP 歸檔提取到指定的目錄,請(qǐng)使用 -e 選項(xiàng):
$ python -m zipfile -e monty.zip target-dir/
對(duì)于一個(gè) ZIP 歸檔中的文件列表,請(qǐng)使用 -l 選項(xiàng):
$ python -m zipfile -l monty.zip
