UTF-8的BOM含義- 碼上快樂

文章推薦指數: 80 %
投票人數:10人

其實很多現代腳本語言,比如Python,其解釋器本身都是能處理BOM的,但是shell卡在這里,沒辦法,只能躺着也中槍。

說起來這也不能怪shell,因為BOM本身違反 ... 碼上快樂 首頁 榜單 標簽 關於 搜索 相關內容   簡體   繁體 UTF-8的BOM含義 本文轉載自   kris_zhang   查看原文   2017-03-3011:25   12039    BOM/ UTF-8 BOM的介紹 在github上寫md文件的時候,發現生成自己blog時,報出一個錯誤是讓使用UTF-8編碼,然后在Notepad++上把文件轉成UTF-8時,發現菜單中有"UTF-8無BOM編碼格式"。

上網查了一下BOM的定義:byteordermark這個是為UTF-16和UTF-32准備的,用於標記字節序(byteorder)。

「UTF-8」和「帶BOM的UTF-8」的區別就是有沒有BOM。

即文件開頭有沒有U+FEFF。

BOM的愛恨情仇 知乎上有個比較好的文章,講了BOM問題,下面直接引用了原文: 作者:陳甫鵃鏈接:https://www.zhihu.com/question/20167122/answer/14199022來源:知乎著作權歸作者所有。

商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

首先,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(Multiplebyte)文本文件,就只能借助這種小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的useutf8,都比BOM簡單而且可靠。

另一個好消息是,即使是必須在Windows和UNIX之間切換的朋友也不會悲催。

幸虧在UNIX環境下我們還有VIM這種神器,即使遇到BOM擋道,我們也可以通過setnobomb;setfileencoding=utf8;w三條命令解決問題。

最后回頭想想,似乎也真就只有Windows堅持用BOM了。

P.S.:本問題是自己的第150個回答。

突然發現自己回答得很少很少⋯⋯P.S.2:突然想起需要解釋一下為什么說VIM去除bomb的操作需要在UNIX下完成。

因為VIM在Windows環境下有一個奇怪的bug,總是把UTF-16文件識別成二進制文件,而UNIX(Linux或者Mac都可以)下VIM則無問題。

這個問題從VIM6.8一直跟着我到VIM7.3。

目前尚不清楚這是VIM的bug還是我自己那個.vimrc文件的bug。

如有高手解答不勝感激。

@引用結束 總結 以下是一些經典語錄: HTML有charset屬性,XML有encoding屬性,沒必要拉BOM撐場面 UTF-16這種編碼連ASCII都雙字節,實在不適用於做網頁 通常BOM是用來標示Unicode純文本字節流的,讓文本處理程序識別txt文件是哪個Unicode編碼(UTF-8,UTF-16BE,UTF-16LE) Windows相對對BOM處理比較好,打開文本文件時它會自動識別並剔除BOM. Windows的設計者希望能在用戶不注意的情況下同時兼容Unicode和非Unicode(Multiplebyte)文本文件. Linux一步到位進入UTF-8,過渡期至少經歷了三到四年. BOM不受歡迎主要是在UNIX環境下,因為很多UNIX程序不鳥BOM。

因為BOM本身違反了一個UNIX設計的常見原則,就是文檔中存在的數據必須可見。

UNIX環境下我們還有VIM這種神器,即使遇到BOM擋道,我們也可以通過setnobomb;setfileencoding=utf8;w三條命令解決問題。

似乎也真就只有Windows堅持用BOM了。

UTF-8不需要BOM,所以不含BOM的UTF-8才是標准形式. 微軟在UTF-8中使用BOM是因為這樣可以把UTF-8和ASCII等編碼明確區分開 UTF-8的網頁代碼不應使用BOM,否則常常會出錯 寫C++代碼建議程序要在windows和mac還有linux上運行的話,源代碼最好保存成utf-8帶bom的格式,這樣比較通用一些。

而用utf-16無論大端還是小端,g++都不認的。

或者用utf-8不帶bom格式,然后代碼不要出現非ascii127以后的字符。

帶用bom的utf-8也是符合國際標准的 微軟在堅持使用bom上沒有錯,因為這是在為用戶考慮的。

也許給我們這些寫程序的帶來了不便,但是,計算機最廣泛的用戶不是程序員。

帶頭的鵝和去頭的鵝,有些編輯器比較傻會把去頭的鵝認成鴨子 以UTF-8格式編碼,從notepad++-->Mongodb里面復制東西的時候,莫名其妙多了不少的字節數。

如果不安裝notepad++,使用默認的記事本,那就更是個坑,默認有bom,你還無法選擇。

就是因為這個bom,CSV導入mongodb時,第一個字段總是不正常,直接導致用第一個字段作為條件find時,出不了結果! utf8對ascii的兼容確實是它的好,但是這個優點在某些時候恰恰成了隱藏問題的缺點。

因此bom大法好,加bom保平安. 為什么windows的記事本要強行給utf8加bom的原因——為了兼容舊系統的編碼問題,unix陣營放棄帶bom的utf8——為了讓它們的上古程序能繼續運行下去,這個各自有自己利益訴求的差異決定其實並不對錯 參考: https://www.zhihu.com/question/20167122 http://jimliu.net/2015/03/07/something-about-encoding-extra/ × 免責聲明! 本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。

如果侵犯了您的隱私權益,請聯系本站郵箱[email protected]刪除。

猜您在找 UTF-8BOM頭 UTF-8與UTF-8(BOM)區別 UTF-8與UTF-8(BOM)區別 UTF-8帶BOM和不帶BOM的轉換 UTF-8和UTF—8Bom的區別(轉) UTF-8(withBOM)與UTF-8相互轉換 【改】utf-8的去掉BOM的方法 UTF-8BOM(EFBBBF) utf-8無bom格式編碼 python帶BOM頭utf-8的響應解碼   粵ICP備18138465號   ©2018-2022CODEPRJ.COM



請為這篇文章評分?