為什麼Linux對非UTF-8編碼支持那麼弱呢?

在Win XP上用zip壓縮一個中文文件名的包放到Linux上解壓,然後馬上就亂碼了。

原因是zip並沒有記錄原文件名的編碼。

為什麼Linux對本地化編碼兼容這麼弱呢?我知道可以通過locale文件修改,但改了這個就顧不了另外一個,相反,Windows就做得很好,至少本地版本的系統對本地化編碼都兼容得很好。


先對症下藥吧:

unzip -O cp936
LC_ALL=zh_CN.gb2312 unzip # 一鍵轉區,哼
p7zip

然後解釋一下為什麼默認不自帶這類功能:

  • 首先 zip 是個大坑。支持 zip 的軟體多了,有人(info-zip)提什麼統一用 Unicode 的提議很快就會被淹沒。最後的結果就是 Windows 上普遍通行使用本地編碼的 zip 文件,你換個語言的 Windows 都能給你撲街。(成功轉型升級的都是不用 zip 後綴名的,你看人 jar。)
  • 其次寫 Linux 的人就是懶。是人哪有不懶的?UTF-8 又兼容 ASCII 又能完整表示 Unicode,當然要變成默認啊。既然能完整表示 Unicode,一般人都想不起來去用別的編碼。
  • 當然現代 Linux 上你要用別的編碼的 char* 也不是不可以,前面那個 LC_ALL 你折騰一下就行。問題是你用用 EUC-CN(GB 2312)就想寫個「朱鎔基」寫個火星文,結果不得不換成 GBK。換成 GBK 這可噁心啦,漢字第二位元組各種和 ASCII 重疊,隨地冒幾個 | ] 你就能抓狂了。你比 UTF-8 多付出那麼多,搞到最後用 GBK 還是不能寫 na?ve 寫 U+1F4A2,還得拓展到 GB 18030 才行。GB 18030 本身倒沒什麼問題,可人是 GBK 的拓展,該有的問題你繼續有啊。哦我還沒提 Big5 呢,人五大碼連 " " 都能給你重疊。字元串爆炸分分鐘的事情,誰敢用?

另外 Windows 幾乎是只兼容本地化編碼和 Unicode(UTF-16LE,經常被 conhost 之類的東西搞成 UCS-2),你中文的開一個別的奇怪語言的系統的程序看看?日本 galgame 甚至還有故意用非 Unicode 模式發行的呢。


說Linux對非UTF-8支持弱的,我拿個非GBK的編碼比如Big5或者SJIS的zip文件或者App給你,看你在中文Windows折騰的多還是中文Linux折騰的多吧。

充分了解之後再下結論是個好習慣。


真是too young啊。

你用英文版windows試試?Linux和英文windows這叫國際慣例。中文windows這叫中國特色。

國內所有所謂的windows編碼問題都是中文版windows的鍋,但這個鍋不是微軟的,是工信部的。

當年工信部規定國內所有中文軟體必須使用GB編碼,所以微軟才沒有早點為中文版windows轉unicode。

當然好像日本改unicode也挺晚的,沒具體研究過。

總之,官僚主義害死人

===補充===

我當然知道GB比UNICODE早,但是既然UNICODE出來了,就應該與時俱進。如果早點普及UNICODE,哪有現在這麼多編碼問題。連阿里開放平台介面里都一堆用GB編碼的,以致於某些地方不得不使用HTTP標準中已經標記為作廢的功能。

我的回答只是要告訴樓主,不是LINUX對非UTF8支持弱,是因為中文windows的歷史遺留問題導致了他現在的麻煩——當然舊版ZIP不支持國際編碼也要背一半的鍋。

說我沒見過win95和dos的那位可以去洗洗睡了,用機器碼寫程序的事我都干過,win95和dos算什麼。


別用垃圾linux就好了

Windows 10保平安

Linux到現在連個圖形界面都沒有,連個wifi都連不上,adsl撥號工具都沒,天翼adsl撥號管家也安裝不上,linux怎麼還不去死?


這不是 Linux 的問題,是你自己跨越了幾個年代的問題。下面說詳細一點。

UTF-8 也好,GB2312 也好,UTF-16 也好,都是 encoding。每個操作系統都有一個 default encoding。那麼現在的問題是,如果一個文件要跨越多個文件系統,在文件里必須有一個 meta-data 說明數據是如何 encoding 的,而且各種操作系統都必須知道如何取這個 meta-data。

問題是,在 XP 的年代,沒有規定這麼一個 meta-data。就算是到了現在,也沒有這麼一個統一的 meta-data。一方面是不好協調所有文件格式,另一方面,UTF-8 大行其道,所以很多系統也就默認用 UTF-8 了。

所以這不是標準支持的問題,而是目前根本沒有一個標準。沒有標準的原因有一部分因為 80% 的情況下,不需要這個標準。


Windows 就做得很好?

題主知不知道 Windows 的高級語言設置里有一個選項,來設置非 Unicode 程序的默認編碼,其實就是一個全局 fallback ,在簡體中文系統上就是上古年代的 GBK/CP936 (漢字內碼擴展規範) 。用英文版系統的亞洲人肯定都折騰過這個設置,否則舊軟體各種亂碼。如果你想臨時換成某個編碼(對於非 Unicode 程序)怎麼辦?還有 AppLocale 這種工具(打日本遊戲的應該都很熟悉)。

你用的壓縮軟體恰好對於 zip 這種沒有編碼信息的文件使用了系統 fallback 編碼,甚至可能直接 hardcode 使用了 GBK (尤其是國內的那些,畢竟國內幾乎所有的 zip 都是 GBK 編碼的);壓縮的時候也要特地轉換成 GBK (即使 Windows 內碼已經使用了 UTF-16 ),來遷就大陸地區的 de facto 。如果你去下幾個日本或者港台的 zip 包解壓,就知道有多痛苦了: Big5 (及其各種變體)、 Shift JIS 等等夠你受的……很多壓縮軟體根本沒有辦法解決亂碼,少數幾個能指定 zip 編碼的壓縮軟體也都把這個功能藏得比較深,找到後還得憑經驗一個個嘗試。

所以錯的是 zip 這種既沒有 meta data ,又不強制使用 Unicode 的數據格式。

更正:感謝 @Belleve ,2006年發布的新標準中, zip 文件頭有一個 bit 指定文件名是否是 UTF-8 (參考資料),但沒有一個欄位用來表示如果不是 UTF-8 的話是哪一個編碼。(知道了以後我就對於 Windows 下那些即使如此為了「向後兼容」仍然死活不用 UTF-8 甚至還忽略這個 bit 的壓縮軟體表示憤怒。總之還是盡量繞開 zip 這個大坑就是……)

而且對於 zip ,想要「兼容」還有一個難點——一個壓縮包中所有文件的文件名總長度一般不大,而且大部分是英文字元,想要「啟發式」地自動猜測編碼準確度太低,不像網頁。而且即使是網頁,瀏覽器用了那麼多黑科技還有時會「猜錯」使用奇怪編碼又不標明的上古網頁。

Linux 下的 unzip 還有一個未被上游接受的 patch ,可以直接用一個命令行參數指定編碼。搜搜 unzip-iconv 就行。如果你想要有類似 Windows 下的「本地化」體驗,甚至可以 alias unzip=『unzip -O gbk" 。我覺得用起來比 Windows 下的大多數 zip 編碼解決方案都要好多了。


因為 Linux 發家的時候 utf-8 已經發明了,所以很多程序沒考慮遺留編碼。當然 zip 格式也有責任。

DOS/Windows 則經歷過萬碼奔騰的黑暗年代,必須對遺留編碼做兼容。BOM 問題就是這麼來的……


是廣泛使用的舊版zip標準本身就沒有規定也不能指定文件名的內碼 導致dos/win用ansi linux和osx默認都utf8


這充分說明了zip協議垃圾,

轉其他壓縮吧,7z,tar之類的,

要是說自動判斷編碼的話,

遇到無法正確判斷照樣亂碼,

一般情況,單獨一個漢字很可能無法正確判斷編碼,


明顯是 zip 本身的問題,沒有保存文件名編碼信息。壓縮的時候用的 GBK,解壓的時候用的是 UTF-8,當然會出錯。解決方法很簡單:

1. 不用 zip,改用 7z, tar.gz, tar.xz, tar.bz2 之類的

2. 用 convmv 轉換編碼

3. 使用解決了亂碼補丁的 unzip

4. 虛擬機裝一個簡體中文的 Windows

5. wine winrar, p7zip 之類的

6. 更改 locale


七律-gb2312

手持兩把錕斤拷,口中疾呼燙燙燙。腳踏千朵屯屯屯,笑看萬物鍩鍩鍩。


吐槽Windows編碼環境的用過AppLocale嗎?

當年曹操傳都靠這個不然就是變巨。

Windows 7以來Unicode程序逐漸主流於是沒有官方支持了,但是很輕易的可以安裝上,可以繞開一個安裝bug。


認為Linux中文支持力度差的強烈推薦使用Mac,這是面向程序開發人員的介於Windows和UNIX之間的好平台,在美國研發部門Mac使用率超25%,而且大牛居多。


當你同時擁有中文非Unicode 的zip 韓語的非Unicode 的zip 日語的非Unicode 的zip你就知道了………

非Unicode 反人類……所以Linux 看不出來……當然你要想的話其實也可以…直接export LANG=zh_CH.GBK 嘍……但是你就會發現其他語言就瘋了……

Windows 的區域設置裡面有一個非Unicode 語言…你改一下那個就知道windows 是通過什麼知道的了……


用unar即可。


倖存者偏差,你試試用外文版Windows


zip的壓縮法本身就很弱。

win下

你做一個有以漢字為文件名的zip包,然後控制面板里的地區和語言里最右邊選項卡里在非Unicode軟體選用哪國標準那裡,換一個別的,設置好了重啟,重啟完了你的zip包里的以漢字為文件名的文件就變成別的了。

但是7z沒事,因為它支持文件名Unicode編碼。

rar可能也支持吧,不太清楚…

…托這個還有很多RPG maker相關的軟體的福氣,我不用app就得不停重啟電腦了…


歷史原因,不同操作系統對編碼沒有統一的標準。這個在Windows上也一樣,如果查看軟體沒有自動檢測編碼的功能,看Linux 或MacOSX 發送的文件一樣可以是亂碼。

打個跑題的比方,有些使用工具生成的網頁形式的報告,由於沒有在頭部沒有指明使用的編碼,在不同OS的不同瀏覽器里顯示,有的正常,有的亂碼。這個例子跟操作系統對不同文件編碼的兼容性,道理是一樣的。

由於沒有對文件指定編碼格式的頭欄位或元數據,不同操作系統使用各自的默認編碼格式,文件在不同操作系統間移植時,就需要自己去做兼容轉換。如windows上文件移植到Linux,可以使用iconv對文件名進行轉換,使用dos2unix對內容進行轉換。另外,跨程序之間,比如客戶端與伺服器間,如果有硬編碼的中文字元,往往也需要使用一組編碼轉換函數進行轉換。


推薦閱讀:

Nginx 和 Apache 在Linux 下的性能表現誰更好?
Arch Linux的用戶都有理想主義傾向嗎?
如何看Linux各發行版的出廠桌面環境不是很精緻?
按照我的這個簡歷描述的技能是否可以找到實習生或者直接的IT工作?
I/O會一直佔用CPU嗎?

TAG:Linux | 計算機 | 字元編碼 | 編碼 | UTF-8 |