zipfile --- 處理 ZIP 封存檔案

原始碼:Lib/zipfile/


ZIP 檔案格式是一種常見的封存 (archive) 與壓縮標準。本模組提供了建立、讀取、寫入、附加與列出 ZIP 檔案的工具。任何對本模組的進階使用都將需要對 PKZIP Application Note 中定義的格式有所理解。

本模組目前不處理多磁碟 ZIP 檔案。它可以處理使用 ZIP64 擴充(即大於 4 GiB 的 ZIP 檔案)的 ZIP 檔案。它支援解密 ZIP 封存檔案中的加密檔案,但目前無法建立加密檔案。解密速度極慢,因為它是在原生 Python 中實作,而不是 C。

本模組定義了以下項目:

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。為了向後相容,舊的受保護名稱仍可作為一個特性繼續運作。

zipfile.is_zipfile(filename)

如果 filename 根據其魔術數字(magic number)是一個有效的 ZIP 檔案,則回傳 True,否則回傳 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 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;無法識別的值將導致引發 NotImplementedError。如果指定了 ZIP_DEFLATED、ZIP_BZIP2 或 ZIP_LZMA,但對應的模組(zlib、bz2 或 lzma)不可用,則會引發 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)。

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.3 版的變更: 新增對於 bzip2 和 lzma 壓縮的支援。

在 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.close()

關閉封存檔案。你必須在結束程式前呼叫 close(),否則必要的記錄將不會被寫入。

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 參數。

備註

open()、read() 和 extract() 方法可以接受一個檔名或一個 ZipInfo 物件。當你嘗試讀取一個包含重複名稱成員的 ZIP 檔案時,你會發現這很有用。

在 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.setpassword(pwd)

設定 pwd(一個 bytes 物件)為解壓縮加密檔案的預設密碼。

ZipFile.read(name, pwd=None)

回傳封存檔案中 name 檔案的位元組。name 是封存檔案中檔案的名稱,或是一個 ZipInfo 物件。封存檔案必須以讀取或附加模式開啟。pwd 是用於加密檔案的密碼,為一個 bytes 物件,如果指定,將會覆寫用 setpassword() 設定的預設密碼。在一個使用 ZIP_STORED、ZIP_DEFLATED、ZIP_BZIP2 或 ZIP_LZMA 以外壓縮方法的 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。

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

要使用的偵錯輸出層級。可以從 0(預設,無輸出)設定到 3(最多輸出)。偵錯資訊會被寫入到 sys.stdout。

ZipFile.comment

與 ZIP 檔案關聯的註解,為一個 bytes 物件。如果為一個以 'w'、'x' 或 'a' 模式建立的 ZipFile 實例指派註解,其長度不應超過 65535 位元組。超過此長度的註解將被截斷。

Path 物件

class zipfile.Path(root, at='')

從一個 root zipfile(它可以是一個 ZipFile 實例或一個適合傳遞給 ZipFile 建構函式的 file)建構一個 Path 物件。

at 指定此 Path 在 zipfile 中的位置,例如 'dir/file.txt'、'dir/' 或 ''。預設為空字串,表示根目錄。

備註

Path 類別不會清理 ZIP 封存檔案內的檔名。與 ZipFile.extract() 和 ZipFile.extractall() 方法不同,呼叫者有責任驗證或清理檔名,以防止路徑遍歷漏洞(例如,包含 ".." 或絕對路徑的檔名)。在處理不受信任的封存檔案時,請考慮使用 os.path.abspath() 解析檔名,並使用 os.path.commonpath() 與目標目錄進行核對。

Path 物件公開了 pathlib.Path 物件的以下特性:

Path 物件可以使用 / 運算子或 joinpath 來遍歷。

Path.name

最後的路徑元件。

Path.open(mode='r', *, pwd, **)

在目前路徑上呼叫 ZipFile.open()。允許透過支援的模式 'r'、'w'、'rb'、'wb' 以讀取或寫入、文字或二進位模式開啟。當以文字模式開啟時,位置引數和關鍵字引數會被傳遞給 io.TextIOWrapper,否則會被忽略。pwd 是傳遞給 ZipFile.open() 的 pwd 參數。

在 3.9 版的變更: 新增了對 open 的文字和二進位模式的支援。預設模式現在是文字模式。

在 3.11.2 版的變更: encoding 參數可以作為位置引數提供,而不會導致 TypeError,就像在 3.9 中一樣。需要與未修補的 3.10 和 3.11 版本相容的程式碼,必須將所有 io.TextIOWrapper 引數,包括 encoding,作為關鍵字傳遞。

Path.iterdir()

列舉目前目錄的子項目。

Path.is_dir()

如果目前情境參照到一個目錄,則回傳 True。

Path.is_file()

如果目前情境參照到一個檔案,則回傳 True。

如果目前情境參照到一個符號連結,則回傳 True。

在 3.12 版被加入.

在 3.13 版的變更: 先前,is_symlink 會無條件地回傳 False。

Path.exists()

如果目前情境參照到 zip 檔案中的一個檔案或目錄,則回傳 True。

Path.suffix

最後一個元件中以點分隔的最後一部分(如果有的話)。這通常被稱為副檔名。

在 3.11 版被加入: 新增 Path.suffix 特性。

Path.stem

最後的路徑元件,不含其後綴。

在 3.11 版被加入: 新增 Path.stem 特性。

Path.suffixes

路徑的後綴串列,通常稱為副檔名。

在 3.11 版被加入: 新增 Path.suffixes 特性。

Path.read_text(*, **)

將目前檔案讀取為 unicode 文字。位置引數和關鍵字引數會被傳遞給 io.TextIOWrapper(但 buffer 會根據情境隱式處理)。

在 3.11.2 版的變更: encoding 參數可以作為位置引數提供,而不會導致 TypeError,就像在 3.9 中一樣。需要與未修補的 3.10 和 3.11 版本相容的程式碼,必須將所有 io.TextIOWrapper 引數,包括 encoding,作為關鍵字傳遞。

Path.read_bytes()

將目前檔案讀取為位元組。

Path.joinpath(*other)

回傳一個新的 Path 物件,並將每個 other 引數加入。以下是等效的:

>>> Path(...).joinpath('child').joinpath('grandchild')
>>> Path(...).joinpath('child', 'grandchild')
>>> Path(...) / 'child' / 'grandchild'

在 3.10 版的變更: 在 3.10 之前,joinpath 沒有文件記載,且只接受一個參數。

zipp 專案為舊版 Python 提供了最新的 path 物件功能的向後移植版本。使用 zipp.Path 來取代 zipfile.Path 以提早使用變更。

PyZipFile 物件

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 檔案,並將對應的檔案加入封存檔案。

如果傳給 PyZipFile 的 optimize 參數未被給定或為 -1,則對應的檔案是一個 *.pyc 檔案,如有必要則進行編譯。

如果傳給 PyZipFile 的 optimize 參數為 0、1 或 2,則只有具有該最佳化層級(參閱 compile())的檔案會被加入封存檔案,如有必要則進行編譯。

如果 pathname 是一個檔案,檔名必須以 .py 結尾,且只有(對應的 *.pyc)檔案會被加到頂層(沒有路徑資訊)。如果 pathname 是一個不以 .py 結尾的檔案,將會引發 RuntimeError。如果它是一個目錄,且該目錄不是一個套件目錄,則所有 *.pyc 檔案都會被加到頂層。如果該目錄是一個套件目錄,則所有 *.pyc 都會以檔案路徑的形式被加到套件名稱下,且如果任何子目錄是套件目錄,所有這些都會以排序後的順序遞迴地加入。

basename 僅供內部使用。

filterfunc,如果給定,必須是一個接受單一字串引數的函式。每個路徑(包括每個單獨的完整檔案路徑)在被加入封存檔案之前都會被傳遞給它。如果 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                   # 頂層名稱
test/__init__.pyc            # 套件目錄
test/testall.pyc             # 模組 test.testall
test/bogus/__init__.pyc      # 子套件目錄
test/bogus/myfile.pyc        # 子模組 test.bogus.myfile

在 3.4 版的變更: 新增 filterfunc 參數。

在 3.6.2 版的變更: pathname 參數接受一個 path-like object。

在 3.7 版的變更: 遞迴會對目錄條目進行排序。

ZipInfo 物件

ZipInfo 類別的實例由 ZipFile 物件的 getinfo() 和 infolist() 方法回傳。每個物件儲存關於 ZIP 封存檔案單一成員的資訊。

有一個類別方法可以為檔案系統中的檔案建立一個 ZipInfo 實例:

classmethod ZipInfo.from_file(filename, arcname=None, *, strict_timestamps=True)

為檔案系統上的一個檔案建構一個 ZipInfo 實例,為將其加入 zip 檔案做準備。

filename 應為檔案系統上一個檔案或目錄的路徑。

如果指定了 arcname,它將被用作封存檔案內的名稱。如果未指定 arcname,名稱將與 filename 相同,但會移除任何磁碟機代號和開頭的路徑分隔符。

strict_timestamps 引數,當設為 False 時,允許壓縮早於 1980-01-01 的檔案,代價是將時間戳記設為 1980-01-01。對於晚於 2107-12-31 的檔案,也會有類似的行為,時間戳記同樣會被設為極限值。

在 3.6 版被加入.

在 3.6.2 版的變更: filename 參數接受一個 path-like object。

在 3.8 版的變更: 新增了 strict_timestamps 僅限關鍵字參數。

實例具有以下方法和屬性:

ZipInfo.is_dir()

如果此封存成員是一個目錄,則回傳 True。

這會使用條目的名稱:目錄應總是以 / 結尾。

在 3.6 版被加入.

ZipInfo.filename

封存檔案中檔案的名稱。

ZipInfo.date_time

封存成員的最後修改時間和日期。這是一個包含六個值的元組:

索引

值

0

年(>= 1980)

1

月(從 1 開始)

2

日(從 1 開始)

3

時(從 0 開始)

4

分(從 0 開始)

5

秒(從 0 開始)

備註

ZIP 檔案格式不支援 1980 年以前的時間戳記。

ZipInfo.compress_type

封存成員的壓縮型別。

ZipInfo.comment

個別封存成員的註解,為一個 bytes 物件。

ZipInfo.extra

擴充欄位資料。PKZIP Application Note 包含一些關於此 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 是否有效。

--metadata-encoding <encoding>

為 -l、-e 和 -t 指定成員名稱的編碼。

在 3.11 版被加入.

解壓縮的陷阱

zipfile 模組中的解壓縮可能會由於下面列出的一些陷阱而失敗。

來自檔案本身

解壓縮可能由於不正確的密碼 / CRC 校驗和 / ZIP 格式或不支援的壓縮方法 / 解密而失敗。

檔案系統限制

超出不同檔案系統的限制可能導致解壓縮失敗。例如目錄條目中允許的字元、檔名長度、路徑名長度、單一檔案的大小以及檔案數量等。

資源限制

記憶體或磁碟空間不足會導致解壓縮失敗。例如,解壓縮炸彈(又稱 ZIP bomb)適用於 zipfile 函式庫,可能導致磁碟空間耗盡。

中斷

在解壓縮過程中斷,例如按下 control-C 或終止解壓縮過程,可能導致封存檔案解壓縮不完整。

解壓縮的預設行為

不了解預設的解壓縮行為可能導致非預期的解壓縮結果。例如,當兩次解壓縮同一個封存檔案時,它會不經詢問就覆寫檔案。