檔案壓縮的概論與實務

Posted on 週二 23 一月 2024 in Category

硬碟空間就像〇〇,擠一擠還是有的。

本站有文章介紹過圖片檔案的壓縮格式。 本文將注重於通用檔案壓縮, 也就是 ZIP、7Z、RAR 該怎麼玩。

概論

壓縮技術就是用時間換取空間。

就跟我們把一堆雜物打包到一起,既節省空間,也便於攜帶和收藏。 電腦也是一樣,把檔案壓縮成壓縮檔,節省存儲空間,也便於傳輸和存儲。

舉一個非常不恰當的例,壓縮就像把牛奶製成奶粉,便於運輸和儲藏。而我們通常不直接吸奶粉,而解壓縮就像沖泡奶粉還原成牛奶。

所以,各種形式壓縮檔通常我們是無法直接使用的,軟體會在我們知道和不知道的情況下還原始的形式。

除了常見的檔案壓縮,其實圖片、音樂、影片等媒體檔案的壓制也是一種壓縮。對於多媒體檔案,壓縮/解壓縮也通常稱為編碼/解碼。

本文會提及多媒體壓縮,但專注於解釋通用的檔案壓縮。

從 ZIP 到 RAR5,從 RMVB 到 AV1,壓縮格式千百種,新的演算法和格式還在被發明出來,是因為壓縮演算法的發展,還有對應不同的需求。

壓縮檔的權衡

壓縮技術也是一種工程學,是權衡的藝術。

壓縮技術需要考量很多方面,就像在點技能樹一樣,需要在各個方面做出權衡。

時間 v.s. 容量

其中一點是壓縮和解壓縮的速度和效率, 壓縮減少了多少容量被稱之為壓縮率, 通常的,壓縮速度越慢,檔案越小,解壓縮速度越慢,反之亦然。

例如一個影片,若是解壓縮(解碼)速度比影片播放速度還慢,那影片就會卡得不能看。 而這是通用檔案壓縮容忍的壓縮解壓縮時間就比較寬裕了,會更注重於壓縮率上。

鬆散 v.s. 固實壓縮

固實壓縮是通用檔案壓縮的一個技術,一次壓縮一定量的資料而不是一個檔案。這一定量的資料被稱為一個區塊。他的好處是所有多個小檔案被分入一個區塊的時候會(大幅)提高壓縮率(壓縮檔更小)。

但有些時候,我們只需要壓縮檔用的一兩三個檔案,這個需求便是隨機存取。 固實壓縮若要解壓縮區塊中其中一個檔案,就必須解壓縮整個區塊,這讓隨機存取變成災難。

所以若覺得以後要常常在不解壓縮整個檔案的情況下打開其中的某個檔案,就不要使用固實壓縮,反之亦然。

有損 v.s. 無損壓縮

顧名思義有損壓縮後的檔案就再也不能變成原本的形狀,但可以在損失細節之下讓檔案更小;無損壓縮則保留所有細節,可以完全恢復。 無損壓縮就是壓縮會不會降低原始內容品質,有損壓縮多用於多媒體壓縮,而通用檔案壓縮都是無損壓縮。

媒體檔案再壓縮

現代流通的媒體格式,多已經被有損或無損壓縮的非常極限了,那還有必要對媒體檔案再進行壓縮嗎?

壓縮媒體檔案的其中一個目的,是在可接受期間內被解碼,檔案盡可能的小的同時保留最多資訊(所有細節)。

所以這使得通用檔案壓縮仍能再壓縮媒體檔案。雖然再壓縮的空間可能極小,但擠擠總還是有的。

連續讀寫和隨機讀寫

請注意,這裡的 連續、隨機讀寫 不是前文所述的 鬆散、固實壓縮:雖異曲同工但不盡相同。

壓縮軟體一大好處便是整合小檔案:如果你有看過硬碟跑分,應該可以發現硬碟的隨機讀寫效能遠小於連續讀寫效能,而對一拖拉庫的散裝小檔案通常就是隨機讀寫,而對其進行檔案壓縮會改善這個問題。

壓縮壓縮檔(壓縮檔嵌套,套娃)

壓縮壓縮檔,這種方法應該沒有什麼學名,也就是把壓縮檔再壓縮一次,也就是俗稱的套娃。

一般來說,檔案壓縮有「儲存」和「傳輸」兩個目的,「儲存」需要減少大小的高壓縮率,而「傳輸」會需要加密和分卷。

我會建議「儲存」壓縮後再進行「傳輸」壓縮的套娃壓縮法。在這種情景下「傳輸」壓縮甚至不需要壓縮,僅加密。

常見問題

檔名過長

收納的過程便是再包裝:盡量扁平化資料夾,說人話就是減少資料夾一層包一層,以及使用儘量短的檔名。

這不僅會使得壓縮檔看上去更簡潔,甚至可以提高壓縮率使得壓縮檔更小:在 ZIP 中,沒有資料夾的概念,每個檔案都會記錄路徑,即資料夾和檔名,所以資料夾中的每個檔案都會重複記錄一次資料夾名。

通常作業系統(檔案系統)會對檔案的全路徑長度做限制,太長的路徑會造成解壓縮失敗。例如,你在解壓縮的時候,在某個資料夾裡解壓縮失敗,但是在某個槽下直接解壓縮卻成功即是這種問題。

檔名亂碼

有時候下載到的壓縮檔案,內容的檔名是一堆亂碼,這是由於早期的作業系統和壓縮軟體,並沒有考慮到當今的社會和網路如此的全球化,所以遇到不同語系的壓縮檔案就會亂碼。

正統的解決方式是修改作業系統的預設編碼;但我們也可以使用例如 Bandizip 之類有修改編碼功能的壓縮軟體。

詳細的文字編碼問題有點複雜,有機會再撰文贅述。

檔案類型

常見的壓縮檔類型有以下幾種:

  • ZIP:可能是現在流通最廣的壓縮檔格式,有夠用的功能和廣泛軟體的支援。
  • 7Z:開源壓縮檔的代表,原生於 7-Zip,以高效率著稱。
  • RAR:商業壓縮檔的代表,原生於 WinRAR,有著豐富的功能。
  • TAR.GZ:Linux 上的代表,分為打包而不壓縮的 TAR 和只能壓縮一個檔案的 GZ。

順帶一提,壓縮軟體 不等於 壓縮檔案格式 不等於 壓縮演算法, 但大家一般不會去修改預設的檔案格式和演算法,有機會再撰文贅述。

不同的方法各有優劣,與各種應用場景的相性也不同,也是本文希望探討的地方。

實務

本文的指令使用 7-Zip 軟體。請見 7-Zip 的 指令說明檔

  • 分卷 -v4g:若內容很大很大,例如一些遊戲,就可以進行分卷,分卷也便於儲存和在網路上傳輸,雖然硬碟的單文件上限很難碰到,但很多網路空間均有檔案大小上限,可以以此決定分卷大小;就算沒有超過上限,相比之下,分卷上傳也能顯著降低下載、上傳失敗時起肖的程度。

  • 固實 -ms=on:固實壓縮的概念是 將多個檔案變成一塊 而不是 以單一檔案為單位 進行壓縮。7Z 和 RAR 均可支援,ZIP 沒有。好處是在某些情境下可以增加壓縮率使得檔案更小。壞處是喪失了隨機存取的特性,使得在取用單一檔案的時候連同附近的其他檔案也會需要一起被解壓縮,這會浪費時間和算力。所以需要按需啟用。

  • 格式 -t7z:通常認為,7Z 格式比 ZIP 格式壓縮率更好(更小);但 ZIP 有超廣泛的支援;而 RAR 格式具有獨到的恢復功能,可以在網路傳輸中使用,若出現壞檔可以試試運氣修復看看,但 RAR 是專有格式,僅能使用 WinRAR 壓縮。

  • 編碼 -mcu=on:ZIP 的文字編碼限制寬鬆,需要強制使用 Unicode 才能保證在不同語系的作業系統上可以正常使用。

使用場景

同人誌、漫畫、雜誌、CG、圖包

ZIP 格式、最大壓縮率、萬國碼:-tzip -mx=9 -mcu=on

這類資源大多是一拖拉庫的有序或無序圖片,而 ZIP 壓縮是被廣泛支援的幾乎事實標準,諸多的漫畫閱讀器均可直接讀取壓縮檔而不需要解壓縮,非固實壓縮也使得可以隨機存取,實現快速跳轉頁面。建議在資料夾中修改檔名為位數適當的前置〇的流水號。再次提醒盡量扁平化資料夾,以及需要注意 ZIP 在文字編碼上的問題。

CB* 格式的本質就是壓縮檔,甚至內容結構都沒有規範(各閱讀器不同),例如 CBZ 就是 ZIP、CB7 就是 7Z、CBR 就是 RAR。

電子書

EPUB 也是一種 ZIP:-tzip -mx=9 -mcu=on

(跑題)使用 EPUB 格式可以像紙質書一樣讓電子書圖文並茂並且有豐富的排版,相比於 DOCX 的繁雜和 PDF 的臃腫死板,EPUB 可以讓讀者用他們自己舒服和習慣的字形字色背景閱讀。製作 EPUB 也需要有 HTML、CSS 的知識。EPUB 的本質是安排好的 ZIP,所以可以提高壓縮率直接再壓縮 EPUB 檔,而不需要再套一層其他壓縮格式。

據我實驗所知,一些 EPUB 壓縮軟體並沒有使用最高壓縮率,特定情況下可以通過再壓縮節省空間。

遊戲、程式、備份檔

7Z 格式、最大壓縮率、固實壓縮:-t7z -mx=9 -ms=on

7Z 相比於 ZIP 有更好的壓縮率,而遊戲、程式必須全部解壓縮展開後才可執行,故不存在需要在壓縮檔內隨機存取的情況,遊戲、程式內通常也富含小檔案,固實壓縮在這個情景下可以有較好的表現。請注意 7Z 格式預設固實壓縮模式是啟用的。

音樂、影片、動畫、電影

7Z 格式、最大壓縮率、鬆散壓縮:-t7z -mx=9 -ms=off

音樂、影片等本是經過高度壓縮的檔案格式,不同的檔案格式緊密程度不同,通常再用檔案壓縮效益不大,甚至可以不需要再以檔案壓縮。若不著急或這電腦有多餘算力,或是就是要扣那幾啪的空間,當然可以選擇最高的壓縮率。而取消固實壓縮模式因為在這個情景下作用不大(甚至可能是反效果),還可以帶來隨機存取的好處,讓你在讀取其中某個檔案的時候不需要浪費時間和算力讀取其他檔案,尤其是影片每個可能都是 GiB 等級的大檔案,這個優勢會尤其明顯。

壓縮壓縮檔(壓縮檔嵌套,套娃)

7Z/RAR 格式、無壓縮、分卷、萬國碼:-t7z -mx=0 -v4g

上述多種型別內容的混合,先分門別類的壓縮後,在以一個無壓縮率的壓縮檔打包,同時可以做加密和分卷的動作。