Watch at Ease看見世界,讀懂生活。

科技 · 實用指南

Python出現BadZipFile?分清ZIP結構、CRC與必要檔案

PK開頭、可列出檔案與完整性檢查通過,回答不同問題。修復前先保留原件。

原創編輯插畫:ZIP結構、CRC與預期內容須分別檢查。
原創編輯插畫:ZIP結構、CRC與預期內容須分別檢查。 Watch at Ease

Python顯示BadZipFile: File is not a zip file時,先保留確切輸入與完整錯誤。這不代表改副檔名、清快取或截掉位元組就能還原預期壓縮檔。

分開檢查三關:能否解析結構、能否讀取成員而未檢出CRC錯誤,以及是否包含本次交付要求的檔案。我們執行五個小型合成測試,說明三種結論不能互換。

1. 保留輸入與失敗階段

記錄實際路徑、位元組數、SHA-256、Python版本及完整例外。原件不動,用副本排查。本機摘要只能識別位元組;須與同一產物的獨立可信參考比較,才有來源驗證意義。

下載檔案應確認授權來源與版本,檢查保存的是否其實為錯誤頁或登入頁。自行產生ZIP時,須等寫入端關閉才開啟讀取;Python文件說明關閉會寫入必要紀錄。勿以w模式開啟原件,因為它會截斷檔案。

2. 先看結構,再讀取全部內容

對來源已知且適度小的候選檔,呼叫zipfile.is_zipfile(path),再以with zipfile.ZipFile(path, "r") as z開啟並查看z.infolist()。記錄名稱、file_size、compress_size及compress_type。建立物件已失敗,就不能認定成員列表成功;PKWARE要求結束紀錄,PK兩字不能證明目錄完整。

評估來源與資源範圍後,才在相同上下文呼叫z.testzip()。它讀取成員,回傳第一個壞檔名,所查項目通過則為None。例外須保留為未解決結果。宣告大小有助評估,但不是強制資源限制;大型或不可信封存檔應在有硬性限制的隔離環境處理。

3. 比較五組實測

我們在Python3.12.14建立小型BytesIO樣本,未執行解壓。正常136位元組ZIP列出report.txt,testzip()為None;移除22位元組結束紀錄後,114位元組仍以PK開頭,但is_zipfile()為False,建立ZipFile時出現BadZipFile。

翻轉一個未壓縮內容位元組而不改CRC,大小仍是136;is_zipfile()為True,列表仍有report.txt,但testzip()回傳report.txt。合法22位元組空ZIP為True與None,列表卻空白。20位元組HTML未獲ZIP辨識。這是階段對照,不是你的檔案診斷或全部ZIP功能測試。

4. 修復已證實原因,再驗收內容

格式錯誤或下載不全時,從正常授權管道另存新檔,核對同一產物的可信參考。產生端未收尾則重新建立並正確關閉。若例外指出不支援壓縮或加密功能,先核對讀取器能力,別僅憑例外認定損毀;Python zipfile不處理分卷ZIP。

記錄檔案摘要、結構、CRC、必要成員名稱與最終應用測試。CRC通過不驗證發布者、內容安全或交付完整;缺必要檔案時,即使testzip()為None也不能驗收。勿對唯一原件套通用簽名截斷補丁,能開啟不代表缺失資料已還原。

原創編輯插畫:Python3.12.14小型合成樣本的實際結果。
原創編輯插畫:Python3.12.14小型合成樣本的實際結果。 Watch at Ease