May 3, 2009 @ 4:08 pm · Filed under 流水賬
一直以來,我發現在 Mac OS X 中,不論用 Stuffit Expander 還是命令列下的 unzip,解壓縮 Windows 下產生的某些 ZIP 檔案時,解出來的中文檔案名稱會變成亂碼。不過,這種情況出現的次數很少,沒有引起我的重視。今天終於覺得不能忍了,以幾個簡單關鍵詞在 Google 上搜尋,好像沒有發現專門說這件事情的。於是決心花點時間研究它。
我在 Windows 下的 ZIP 檔案大多數是用 7-Zip 這個自由軟體產生的。雖然它的強項在於自己的 7z 格式,不過出於相容性的考慮,我只是用它壓縮 ZIP 格式檔案,並解壓縮所有常見的壓縮檔格式。ZIP 檔案標準自創立之初就沒有、現在也沒有記錄檔案名稱編碼的資訊,所以有很大一批 ZIP 檔案都是以壓縮包的建立者本地 locale 編碼的,比如我遇到問題的幾個 ZIP 檔案內部的檔案名稱就是用簡體中文 GBK 編碼的。而我 Mac OS X 的 locale 是 en_US.UTF-8,解開後自然不能正確識別 GBK 編碼的檔案名稱了。
閱讀了 ZIP 檔案格式這個 Wikipedia 條目,我發現最新的 ZIP 標準中建議使用 UTF-8 作為檔案名稱的編碼。這一點並不出乎意料,顯然對於跨平台的需求,UTF-8 的編碼是最理想的選擇。下面的問題就是如何讓 7-Zip 產生以 UTF-8 編碼被壓縮檔名的 ZIP 檔案了。
在 Windows 下進行實驗,我發現一個有意思的現象:當 Windows 系統的 locale 為簡體中文(中國)時(“控制台-地區和語言選項-進階-為非Unicode程式的語言選擇 – Chinese (PRC)”),7-Zip 壓縮出來的 ZIP 檔案以 GBK 編碼被壓縮檔名;而當 Windows 系統的 locale 為英語(美國)時,壓縮出來的 ZIP 檔案編碼竟然是 UTF-8!此外,在中文 locale 下,不論是以 GBK 還是 UTF-8 編碼檔案名稱的 ZIP 檔案都能正常解開;而在英文 locale 下,只能解開 UTF-8 編碼的檔案,GBK 編碼的檔案解出來就是亂碼。這表明, 7-Zip 是有處理 UTF-8 編碼檔案名稱的功能的。但是,為什麼僅僅對英語(美國)字碼頁(也就是最基本的 ASCII )才會使用 UTF-8 呢?
繼續尋找,發現 UTF-8 的版本歷史裡面,自從 4.58 版本以來引入了 ZIP 內部檔案名稱編碼的概念。預設模式是,對於產生 ZIP 檔案的檔案名稱,如果當前 locale 字碼頁中有相應字元,就用當前字碼頁;如果沒有,就使用 UTF-8。同時,7-Zip 也提供了兩個模式,強制以 UTF-8 編碼檔案名稱,或強制以當前 locale 編碼檔案名稱(即不作轉換)。
瞭解了這一點,解決方案就變得簡單了:壓縮 ZIP 檔案時,使用 -mcu 選項強制使用 UTF-8 作為壓縮檔名的編碼。圖形介面中的操作如下:
需要注意的是,7-Zip 的 Explorer shell 右鍵菜單中“Add to .zip” 這個項目只能以預設參數產生 ZIP 檔案。如果希望產生在其他平台不出現亂碼的 UTF-8 編碼 ZIP 檔案,就只能使用 “Add to archive…” 功能表項目了。