Gzip

gzip -t 可以檢測 100% 的截斷下載錯誤嗎?

  • January 22, 2022

場景:單個 1g CSV.gz 正在寫入 FTP 文件夾。同時,我的客戶端機器通過 sFTP 連接到該文件夾並嘗試將其拉下。

:在獲取該文件後,無論我在客戶端獲得任何明顯的長度,都可以gzip -t檢測到部分文件並使部分文件失敗,而不管截斷在哪裡?

我認為當片段突然結束時,解壓縮或 -t’esting 會在 99% 的可能截斷點上出錯,但是 gz 結構是否有乾淨的切割點,gzip 會意外報告成功?

不在桌面上的緩解措施(因為如果其中一個在起作用,我不需要問上面的問題。)

  1. 通過另一個網路請求獲取文件長度或 md5。

  2. 通過 FTP 輪詢文件長度並不是很好,因為伺服器可能會偶爾將塊寫入 zip 流。在批處理作業關閉文件句柄之前,將其誤認為是完整的數據集對我的分析來說是致命的。

  3. 由批處理作業給出最終文件長度或散列消除了對這個 Q 的需要,但這給團隊帶來了實施負擔,(對於這個 Q 的目的)可能不存在。

  4. 我們無法通過安排一天中不同時間的讀/寫來避免競爭。

  5. 伺服器未使用原子移動操作。

  6. 我不知道 CSV 行/列計數;它會隨著每個快照和每個集成而改變。也可以說被 gzip 壓縮的文件是這個 Q 的不透明二進制 blob。

  7. 沒有客戶端=> sFTP 網路錯誤在起作用。(那些被擷取和處理;我擔心的是讀取一個在伺服器批處理作業期間仍然偶爾寫入的文件。)

  8. 使用 RESTful API 而不是 sFTP。

沒有找到現有的 SO

一些 SO 涉及處理截斷,但與需要在任何問題上可靠地使整個工作流程失敗相比,它們處於有損可接受的上下文中。(我在醫療數據環境中進行計算,所以我寧願讓伺服器停止並著火,也不願傳播不正確的統計數據。)

gzip 格式的文件包含壓縮數據的長度和未壓縮數據的長度。然而,這是一種古老的格式,長度欄位只有 32 位,所以現在它們被解釋為長度模 2^32(即 4 GiB)。解壓前gzip檢查壓縮數據的校驗和是否正確。解壓後,gzip檢查解壓數據的校驗和是否正確,解壓數據的大小是否正確模2^32。

因此,如果壓縮數據的大小(或解壓縮數據的大小)小於 4 GiB,則 gzip 可以保證檢測到截斷的輸入。但是,對於任意大小的文件,我看不出這些檢查是否足夠的任何理由。如果輸入不是故意設計的,並且其長度以 4 GiB 為模均勻分佈,則壓縮長度和校驗和匹配的機率只有 1/2^64,如果文件在多字節序列的中間或者如果未壓縮數據的長度不匹配。(這並不一定會將機會減少到 1/2^96,因為壓縮長度模 2^32 和未壓縮長度模 2^32 是相關的。)所以只有很小的機會出現未檢測到的錯誤,但它是非零的,和我'

請注意,此分析僅適用於 gzip 壓縮文件由單個流組成的情況。gunzip可以解壓縮由多個連接的流組成的文件,並且無法檢測文件是否包含有效的流序列,但需要更多的流。但是,您的生產鏈可能不會生成多流文件:gzip不會自己生成,您必須手動連接多次執行的輸出,或者使用其他工具(pkzip?)。

伺服器未使用原子移動操作。

不幸的是,我認為沒有一種完全可靠的方法來檢測錯誤,而無需在伺服器完成寫入後計算的外部元數據(長度或加密校驗和)。

引用自:https://unix.stackexchange.com/questions/687386