zipfile --- 處理 ZIP 封存檔案¶
原始碼:Lib/zipfile/
ZIP 檔案格式是一種常見的封存 (archive) 與壓縮標準。本模組提供了建立、讀取、寫入、附加與列出 ZIP 檔案的工具。任何對本模組的進階使用都將需要對 PKZIP Application Note 中定義的格式有所理解。
本模組不處理多組件 (multipart) ZIP 檔案。它可以處理使用 ZIP64 擴充(即大於 4 GiB 的 ZIP 檔案)的 ZIP 檔案。它支援解密 ZIP 封存檔案中的加密檔案,但目前無法建立加密檔案。解密速度極慢,因為它是在原生 Python 中實作,而不是 C。
Handling compressed archives requires optional modules
such as zlib, bz2, lzma, and compression.zstd.
If any of them are missing from your copy of CPython,
look for documentation from your distributor (that is,
whoever provided Python to you).
If you are the distributor, see 可選模組的需求.
本模組定義了以下項目:
- exception zipfile.BadZipFile¶
對於損壞的 ZIP 檔案所引發的錯誤。
在 3.2 版被加入.
- exception zipfile.BadZipfile¶
BadZipFile的別名,為了與舊版 Python 相容。在 3.2 版之後被棄用.
- exception zipfile.LargeZipFile¶
當 ZIP 檔案需要 ZIP64 功能但該功能未被啟用時所引發的錯誤。
- class zipfile.ZipFile
用於讀取和寫入 ZIP 檔案的類別。有關建構函式的詳細資訊,請參閱 ZipFile 物件 章節。
- class zipfile.Path
實作了
pathlib.Path所提供介面子集的類別,包括完整的importlib.resources.abc.Traversable介面。在 3.8 版被加入.
- 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 物件 章節中有所描述。在 3.13 版的變更: 新增了一個公開的
compress_level屬性,以公開先前受保護的_compresslevel。為了向後相容,舊的受保護名稱仍可作為一個特性繼續運作。- _for_archive(archive)¶
Resolve the date_time, compression attributes, and external attributes to suitable defaults as used by
ZipFile.writestr().Returns self for chaining.
在 3.14 版被加入.
- zipfile.is_zipfile(filename)¶
如果 filename 根據其魔術數字(magic number)是一個有效的 ZIP 檔案,則回傳
True,否則回傳False。filename 也可以是一個檔案或類檔案物件。在 3.1 版的變更: 支援檔案和類檔案物件。
- zipfile.ZIP_STORED¶
用於未壓縮封存成員的數值常數。
- zipfile.ZIP_ZSTANDARD¶
用於 Zstandard 壓縮方法的數值常數。這需要
compression.zstd模組。備註
In APPNOTE 6.3.7, the method ID
20was assigned to Zstandard compression. This was changed in APPNOTE 6.3.8 to method ID93to avoid conflicts, with method ID20being deprecated. For compatibility, thezipfilemodule reads both method IDs but will only write data with method ID93.在 3.14 版被加入.
備註
ZIP 檔案格式規範自 2001 年起已包含對 bzip2 壓縮的支援、自 2006 年起支援 LZMA 壓縮、自 2020 年起支援 Zstandard 壓縮。然而某些工具(包括舊版的 Python)不支援這些壓縮方法,可能會完全拒絕處理該 ZIP 檔案,或無法解壓縮個別檔案。
也參考
- PKZIP Application Note
由 Phil Katz(該格式與所用演算法的創造者)所撰寫的關於 ZIP 檔案格式的文件。
- Info-ZIP 首頁
關於 Info-ZIP 專案的 ZIP 封存程式和開發函式庫的資訊。
ZipFile 物件¶
- class zipfile.ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, compresslevel=None, *, strict_timestamps=True, metadata_encoding=None)¶
開啟一個 ZIP 檔案,其中 file 可以是一個檔案的路徑(一個字串)、一個類檔案物件或一個 path-like object。
mode 參數應為
'r'來讀取一個現有檔案、'w'來清空並寫入一個新檔案、'a'來附加到一個現有檔案,或'x'來獨佔性地建立並寫入一個新檔案。如果 mode 為'x'且 file 指向一個現有檔案,將會引發FileExistsError。如果 mode 為'a'且 file 指向一個現有的 ZIP 檔案,則會將額外的檔案加入其中。如果 file 並非指向一個 ZIP 檔案,則一個新的 ZIP 封存檔案會被附加到該檔案之後。這適用於將一個 ZIP 封存檔案附加到另一個檔案(例如python.exe)。如果 mode 為'a'且檔案完全不存在,它會被建立。如果 mode 為'r'或'a',該檔案應為可定位的 (seekable)。compression 是寫入封存檔案時要使用的 ZIP 壓縮方法,應為
ZIP_STORED、ZIP_DEFLATED、ZIP_BZIP2、ZIP_LZMA或ZIP_ZSTANDARD;無法識別的值將導致引發NotImplementedError。如果指定了ZIP_DEFLATED、ZIP_BZIP2、ZIP_LZMA或ZIP_ZSTANDARD,但對應的模組(zlib、bz2、lzma或compression.zstd)不可用,則會引發RuntimeError。預設為ZIP_STORED。如果 allowZip64 為
True(預設值),當 zipfile 大於 4 GiB 時,zipfile 將會建立使用 ZIP64 擴充的 ZIP 檔案。如果為false,當 ZIP 檔案需要 ZIP64 擴充時,zipfile將會引發一個例外。compresslevel 參數控制寫入檔案到封存時使用的壓縮層級。當使用
ZIP_STORED或ZIP_LZMA時,它沒有效果。當使用ZIP_DEFLATED時,接受整數0到9(更多資訊請參閱zlib)。當使用ZIP_BZIP2時,接受整數1到9(更多資訊請參閱bz2)。當使用ZIP_ZSTANDARD時,通常接受整數-131072到22(更多關於檢索有效值及其含義,請參閱CompressionParameter.compression_level)。strict_timestamps 引數,當設為
False時,允許壓縮早於 1980-01-01 的檔案,代價是將時間戳記設為 1980-01-01。對於晚於 2107-12-31 的檔案,也會有類似的行為,時間戳記同樣會被設為極限值。當 mode 為
'r'時,metadata_encoding 可以設為一個編解碼器的名稱,該編解碼器將被用來解碼元資料,例如成員名稱和 ZIP 註解。如果檔案以
'w'、'x'或'a'模式建立,然後在沒有向封存檔案中加入任何檔案的情況下關閉,則適用於空封存檔案的 ZIP 結構將被寫入檔案中。ZipFile 也是一個情境管理器,因此支援
with陳述式。在範例中,myzip 在with陳述式的程式碼區塊執行完畢後會被關閉 --- 即使發生例外也是如此:with ZipFile('spam.zip', 'w') as myzip: myzip.write('eggs.txt')
備註
metadata_encoding 是 ZipFile 的一個實例範圍設定。無法以每個成員為基礎來設定此項。
此屬性是針對舊版實作的變通方法,這些實作會以目前區域編碼或頁碼(主要在 Windows 上)產生帶有名稱的封存檔案。根據 .ZIP 標準,元資料的編碼可以透過封存檔案標頭中的一個旗標指定為 IBM 頁碼(預設)或 UTF-8。該旗標的優先級高於 metadata_encoding,後者是 Python 特有的擴充。
在 3.2 版的變更: 新增
ZipFile作為情境管理器使用的能力。在 3.4 版的變更: ZIP64 擴充預設為啟用。
在 3.5 版的變更: 新增了對寫入不可定位的 (unseekable) 串流的支援。新增了對
'x'模式的支援。在 3.6 版的變更: 先前,對於無法識別的壓縮值,會引發一個單純的
RuntimeError。在 3.6.2 版的變更: file 參數接受一個 path-like object。
在 3.7 版的變更: 新增 compresslevel 參數。
在 3.8 版的變更: strict_timestamps 僅限關鍵字參數。
在 3.11 版的變更: 新增了在讀取 zipfile 目錄和檔案標頭中的元資料時,可指定成員名稱編碼的支援。
- ZipFile.getinfo(name)¶
回傳一個帶有關於封存成員 name 資訊的
ZipInfo物件。對一個目前不包含在封存檔案中的名稱呼叫getinfo()將會引發KeyError。
- ZipFile.infolist()¶
回傳一個串列,其中為每個封存成員包含一個
ZipInfo物件。如果開啟的是一個現有的封存檔案,這些物件的順序與它們在磁碟上實際 ZIP 檔案中的條目順序相同。
- ZipFile.namelist()¶
依名稱回傳封存成員的串列。
- ZipFile.open(name, mode='r', pwd=None, *, force_zip64=False)¶
以二進位類檔案物件的形式存取封存檔案中的一個成員。name 可以是封存檔案內的檔案名稱,或是一個
ZipInfo物件。mode 參數如果包含,則必須是'r'(預設值)或'w'。pwd 是用於解密加密 ZIP 檔案的密碼,為一個bytes物件。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'時,會回傳一個可寫的檔案控點 (file handle),它支援write()方法。當一個可寫的檔案控點開啟時,嘗試讀取或寫入 ZIP 檔案中的其他檔案將會引發ValueError。在這兩種情況下,該類檔案物件也具有
name屬性,它相當於封存檔案內的檔案名稱,以及mode屬性,其值為'rb'或'wb',取決於輸入的模式。寫入檔案時,如果檔案大小預先未知但可能超過 2 GiB,請傳入
force_zip64=True以確保標頭格式能夠支援大檔案。如果檔案大小預先已知,請建構一個設定了file_size的ZipInfo物件,並將其用作 name 參數。在 3.6 版的變更: 移除了對
mode='U'的支援。請使用io.TextIOWrapper以 universal newlines 模式讀取壓縮的文字檔。在 3.6 版的變更:
ZipFile.open()現在可以用於以mode='w'選項將檔案寫入封存檔案。在 3.6 版的變更: 在一個已關閉的 ZipFile 上呼叫
open()將會引發ValueError。先前,會引發一個RuntimeError。在 3.13 版的變更: 為可寫的類檔案物件新增了
name和mode屬性。可讀的類檔案物件的mode屬性值從'r'變更為'rb'。
- ZipFile.extract(member, path=None, pwd=None)¶
從封存檔案中解壓縮一個成員到目前工作目錄;member 必須是其完整名稱或一個
ZipInfo物件。其檔案資訊會被盡可能精確地解壓縮。path 指定一個不同的目錄來解壓縮。member 可以是一個檔名或一個ZipInfo物件。pwd 是用於加密檔案的密碼,為一個bytes物件。回傳建立的正規化路徑(一個目錄或新檔案)。
備註
如果成員檔名是絕對路徑,磁碟機/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 是用於加密檔案的密碼,為一個bytes物件。警告
絕不要在未經事先檢查的情況下,從不受信任的來源解壓縮封存檔案。檔案有可能被建立在 path 之外,例如,成員具有以
"/"開頭的絕對檔名或帶有兩個點".."的檔名。本模組會試圖防止這種情況。請參閱extract()的註解。在 3.6 版的變更: 在一個已關閉的 ZipFile 上呼叫
extractall()將會引發ValueError。先前,會引發一個RuntimeError。在 3.6.2 版的變更: path 參數接受一個 path-like object。
- ZipFile.printdir()¶
將封存檔案的內容目錄印出到
sys.stdout。
- ZipFile.read(name, pwd=None)¶
回傳封存檔案中 name 檔案的位元組。name 是封存檔案中檔案的名稱,或是一個
ZipInfo物件。封存檔案必須以讀取或附加模式開啟。pwd 是用於加密檔案的密碼,為一個bytes物件,如果指定,將會覆寫用setpassword()設定的預設密碼。在一個使用ZIP_STORED、ZIP_DEFLATED、ZIP_BZIP2、ZIP_LZMA或ZIP_ZSTANDARD以外壓縮方法的 ZipFile 上呼叫read()將會引發NotImplementedError。如果對應的壓縮模組不可用,也會引發一個錯誤。在 3.6 版的變更: 在一個已關閉的 ZipFile 上呼叫
read()將會引發ValueError。先前,會引發一個RuntimeError。
- ZipFile.testzip()¶
讀取封存檔案中的所有檔案,並檢查它們的 CRC 和檔案標頭。回傳第一個損壞檔案的名稱,否則回傳
None。在 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'模式開啟。備註
ZIP 檔案標準在歷史上並未指定元資料編碼,但為了互通性 (interoperability) 強烈建議使用 CP437(原始的 IBM PC 編碼)。近期的版本允許(僅)使用 UTF-8。在本模組中,如果成員名稱包含任何非 ASCII 字元,將會自動使用 UTF-8 來寫入。無法以 ASCII 或 UTF-8 以外的任何編碼寫入成員名稱。
備註
封存名稱應相對於封存檔案的根目錄,也就是說,它們不應以路徑分隔符開頭。
備註
如果
arcname(或在未給定arcname時的filename)包含一個空位元組,封存檔案中該檔案的名稱將在空位元組處被截斷。備註
檔名中開頭的斜線可能導致在 Windows 系統上的某些 zip 程式中無法開啟該封存檔案。
在 3.6 版的變更: 在以
'r'模式建立的 ZipFile 或一個已關閉的 ZipFile 上呼叫write()將會引發ValueError。先前,會引發一個RuntimeError。
- ZipFile.writestr(zinfo_or_arcname, data, compress_type=None, compresslevel=None)¶
將一個檔案寫入封存檔案。內容為 data,它可以是一個
str或一個bytes實例;如果它是一個str,它會先被編碼為 UTF-8。zinfo_or_arcname 是它在封存檔案中將被賦予的檔案名稱,或是一個ZipInfo實例。如果它是一個實例,則至少必須給定檔名、日期和時間。如果它是一個名稱,則日期和時間被設為目前的日期和時間。封存檔案必須以'w'、'x'或'a'模式開啟。如果給定,compress_type 將覆寫為建構函式中 compression 參數為新條目指定的值,或覆寫 zinfo_or_arcname(如果它是一個
ZipInfo實例)中的值。同樣地,如果給定 compresslevel,它將覆寫建構函式。備註
當傳遞一個
ZipInfo實例作為 zinfo_or_arcname 參數時,所使用的壓縮方法將是給定的ZipInfo實例的 compress_type 成員中指定的方法。預設情況下,ZipInfo建構函式將此成員設為ZIP_STORED。在 3.2 版的變更: compress_type 引數。
在 3.6 版的變更: 在以
'r'模式建立的 ZipFile 或一個已關閉的 ZipFile 上呼叫writestr()將會引發ValueError。先前,會引發一個RuntimeError。在 3.14 版的變更: Now respects the
SOURCE_DATE_EPOCHenvironment variable. If set, it uses this value as the modification timestamp for the file written into the ZIP archive, instead of using the current time.
- ZipFile.mkdir(zinfo_or_directory, mode=511)¶
在封存檔案內建立一個目錄。如果 zinfo_or_directory 是一個字串,則會在封存檔案內以 mode 引數中指定的模式建立一個目錄。然而,如果 zinfo_or_directory 是一個
ZipInfo實例,則 mode 引數會被忽略。封存檔案必須以
'w'、'x'或'a'模式開啟。在 3.11 版被加入.
以下資料屬性也可用:
- ZipFile.filename¶
ZIP 檔案的名稱。
- ZipFile.debug¶