- UID
- 2
- 帖子
- 42699
- 主題
- 42285
- 精華
- 25
- 積分
- 127750
- 人氣
- 163273
- 點數
- 14448202
- 威望
- 39
- 存點
- 617397903
- 閱讀權限
- 255
- 性別
- 男
- 來自
- 神の國度
- 在線時間
- 12241 小時
- 註冊時間
- 31-5-2003
- 最後登錄
- 24-4-2024
|
RE: 編碼歪傳——番外篇 (下集)
Source: https://www.zhihu.com/question/20167122
受邀。早知道上得山多終遇老虎,在@梁海
老兄面前耍Unicode總會有這一天的⋯⋯
首先,BOM是啥。這個就不解釋了,Wikipedia上很詳細。http://en.wikipedia.org/wiki/Byte_order_mark。
在網頁上使用BOM是個錯誤。BOM設計出來不是用來支援HTML和XML的。要識別文字編碼,HTML有charset屬性,XML有encoding屬性,沒必要拉BOM撐場面。雖然理論上BOM可以用來識別UTF-16
編碼的HTML頁面,但實際工程上很少有人這麼幹。畢竟UTF-16這種編碼連ASCII都雙位元組,實在不適用於做網頁。
其實說BOM是個壞習慣也不盡然。BOM也是Unicode標準的一部分,有它特定的適用範圍。通常BOM是用來標示Unicode純文字位元組流
的,用來提供一種方便的方法讓文字處理程序識別讀入的.txt檔案是哪個Unicode編碼(UTF-8,UTF-16BE,UTF-16LE)。Windows相對對BOM處理比較好,是因為Windows把Unicode識別程式碼整合進了API裡,主要是CreateFile()。打開文字檔時它會自動識別並剔除BOM。Windows用這個有歷史原因,因為它最初脫胎於多字碼頁的環境。而引入Unicode時Windows的設計者又希望能在使用者不注意的情況下同時相容Unicode和非Unicode(Multiple byte)文字檔,就只能借助這種小trick了。相比之下,Linux這樣的系統在多locale的環境中浸染的時間比較短,再加上社區本身也有足夠的動力輕裝前進(吐槽:微軟對相容性的要求確實是到了非常偏執的地步,任何一點破壞相容性的做法都不允許,以至於很多時候是自己綁住自己的雙手),所以乾脆一步到位進入UTF-8。當然中間其實有一段過渡期,比如從最初全UTF-8的GTK+2.0發佈到基本上所有GTK開發者
都棄用多locale的GTK+1.2,我印象中至少經歷了三到四年。
BOM不受歡迎主要是在UNIX環境下,因為很多UNIX程序不鳥BOM。主要問題出在UNIX那個所有指令碼語言
通行的首行#!標示,這東西依賴於shell解析,而很多shell出於相容的考慮不檢測BOM,所以加進BOM時shell會把它解釋為某個普通字元輸入導致破壞#!標示,這就麻煩了。其實很多現代指令碼語言,比如Python,其直譯器本身都是能處理BOM的,但是shell卡在這裡,沒辦法,只能躺著也中槍。說起來這也不能怪shell,因為BOM本身違反了一個UNIX設計的常見原則,就是檔案中存在的資料必須可見。BOM不能作為可見字元被文字編輯器
編輯,就這一條很多UNIX開發者就不滿意。
順便說一句,即使指令碼語言能處理BOM,隨處使用BOM也不是推薦的辦法。各個指令碼語言對Unicode的處理都有自己的一套,Python的 # -*- coding: utf-8 -*-,Perl的use utf8,都比BOM簡單而且可靠。另一個好消息是,即使是必須在Windows和UNIX之間切換的朋友也不會悲催。幸虧在UNIX環境下我們還有VIM這種神器,即使遇到BOM擋道,我們也可以通過 set nobomb; set fileencoding=utf8; w 三條命令解決問題。
最後回頭想想,似乎也真就只有Windows堅持用BOM了。
P.S.:本問題是自己的第150個回答。突然發現自己回答得很少很少⋯⋯
P.S. 2:突然想起需要解釋一下為什麼說VIM去除bomb的操作需要在UNIX下完成。因為VIM在Windows環境下有一個奇怪的bug,總是把UTF-16檔案
識別成二進制檔案,而UNIX(Linux或者Mac都可以)下VIM則無問題
。這個問題從VIM 6.8一直跟著我到VIM 7.3。目前尚不清楚這是VIM的bug還是我自己那個.vimrc檔案的bug。如有高手解答不勝感激。
編輯於 2012-04-10 23:42
知乎使用者
知乎使用者
網頁程式設計中用不用bom我就不說什麼了,因為軟體原因無法使用的就更不能用了。
最近在學習用cocos2d-x,純C++的編碼,如果程式碼中有中文等的非ascii字元出現。發現會出錯。程式碼是在mac 下用xcode 寫的,放到windows 下用vs 編譯。
最後把所有的原始檔轉成了帶bom的格式後編譯通過了,連結失敗,這想這個就不是編碼的問題了。
通常情況下,一般都 會認為在寫C++程式碼的時候不要用中文,但是很多時候我們程式設計師也有想自己看著舒服的時候,為神馬就不能寫中文了?
於是在windows 下寫了一個helloworld.cpp 類型的檔案,輸出內容用中文,然後存為utf-8 帶bom格式,再把它copy到mac 下用g++ 編譯,發現成功通過並且可正常運行,用xcode打開原始檔也正常顯示。
所以,這裡建議程序要在windows 和 mac 還有linux 上運行的話,原始碼最好保存成utf-8 帶bom的格式,這樣比較通用一些。而用utf-16 無論大端還是小端,g++ 都不認的。或者用utf-8 不帶bom格式,然後程式碼不要出現非ascii 127以後的字元。
關於說utf-8 不帶bom 才是標準的,我想應該是帶用個人情緒的說法吧。真正的標準應該是bom是可選的,為什麼可選?因為有些時候不帶bom會出錯,就拿歷史較久遠的windows來講吧,很多國家的使用者都在用windows ,其檔案都是用其本地的ansi 編碼來做的,比如大陸的GBK和GB2013,港台的big5,這些編碼因為針對當地所用的字元制定的,所以呢,其儲存檔案較小,所以會大量使用,並且也大量存在著,微軟不可能不考慮全球幾十億的使用者的檔案而盲目地修改解碼方式,並且微軟也是unicode 制定者之一,所以,帶用bom的utf-8也是符合國際標準的。
或許是因為程序編寫者的個人原因,也許是考慮到效率,很多的程序無法正確區分一個utf-8檔案是否有bom,所以導致了各種亂碼的出現。
個人不想說哪個是標準,也不想用語言去攻擊哪個公司或團體。微軟在堅持使用bom上沒有錯,因為這是在為使用者考慮的。也許給我們這些寫程序的帶來了不便,但是,電腦最廣泛的使用者不是程式設計師。
發佈於 2014-03-11 16:53
Jim Liu
Jim Liu
前端開發話題下的優秀答主
UTF-8因為它的編碼特性
,是位元組序
無關的,所以不需要BOM。
我覺得“帶BOM的UTF-8”這個鍋基本上WINDOWS還是要背的,儘管我不太確定“UTF-8檔案是否可以帶BOM”這個問題,但整因為它不需要,於是很多跨平台
的軟體其實並不支援這種格式。
發佈於 2016-05-31 21:22
知乎使用者
知乎使用者
機器學習話題下的優秀答主
就是帶頭的鵝和去頭的鵝,有些編輯器
比較傻會把去頭的鵝認成鴨子… |
|