UTF-8的BOM含義
BOM的介紹
在github上寫md文件的時(shí)候,發(fā)現(xiàn)生成自己blog時(shí),報(bào)出一個(gè)錯(cuò)誤是讓使用UTF-8編碼,然后在Notepad++上把文件轉(zhuǎn)成UTF-8時(shí),發(fā)現(xiàn)菜單中有"UTF-8無BOM編碼格式"。
上網(wǎng)查了一下BOM的定義:byte order mark
這個(gè)是為UTF-16和UTF-32準(zhǔn)備的,用于標(biāo)記字節(jié)序(byte order)。
「UTF-8」和「帶 BOM 的 UTF-8」的區(qū)別就是有沒有 BOM。即文件開頭有沒有 U+FEFF。
BOM的愛恨情仇
知乎上有個(gè)比較好的文章,講了BOM問題,下面直接引用了原文:
作者:陳甫鸼
鏈接:https://www.zhihu.com/question/20167122/answer/14199022
來源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
首先,BOM是啥。這個(gè)就不解釋了,Wikipedia上很詳細(xì)。http://en.wikipedia.org/wiki/Byte_order_mark。在網(wǎng)頁上使用BOM是個(gè)錯(cuò)誤。BOM設(shè)計(jì)出來不是用來支持HTML和XML的。要識(shí)別文本編碼,HTML有charset屬性,XML有encoding屬性,沒必要拉BOM撐場(chǎng)面。雖然理論上BOM可以用來識(shí)別UTF-16編碼的HTML頁面,但實(shí)際工程上很少有人這么干。畢竟UTF-16這種編碼連ASCII都雙字節(jié),實(shí)在不適用于做網(wǎng)頁。其實(shí)說BOM是個(gè)壞習(xí)慣也不盡然。BOM也是Unicode標(biāo)準(zhǔn)的一部分,有它特定的適用范圍。通常BOM是用來標(biāo)示Unicode純文本字節(jié)流的,用來提供一種方便的方法讓文本處理程序識(shí)別讀入的.txt文件是哪個(gè)Unicode編碼(UTF-8,UTF-16BE,UTF-16LE)。Windows相對(duì)對(duì)BOM處理比較好,是因?yàn)閃indows把Unicode識(shí)別代碼集成進(jìn)了API里,主要是CreateFile()。打開文本文件時(shí)它會(huì)自動(dòng)識(shí)別并剔除BOM。Windows用這個(gè)有歷史原因,因?yàn)樗畛趺撎ビ诙啻a頁的環(huán)境。而引入U(xiǎn)nicode時(shí)Windows的設(shè)計(jì)者又希望能在用戶不注意的情況下同時(shí)兼容Unicode和非Unicode(Multiple byte)文本文件,就只能借助這種小trick了。相比之下,Linux這樣的系統(tǒng)在多l(xiāng)ocale的環(huán)境中浸染的時(shí)間比較短,再加上社區(qū)本身也有足夠的動(dòng)力輕裝前進(jìn)(吐槽:微軟對(duì)兼容性的要求確實(shí)是到了非常偏執(zhí)的地步,任何一點(diǎn)破壞兼容性的做法都不允許,以至于很多時(shí)候是自己綁住自己的雙手),所以干脆一步到位進(jìn)入U(xiǎn)TF-8。當(dāng)然中間其實(shí)有一段過渡期,比如從最初全UTF-8的GTK+2.0發(fā)布到基本上所有GTK開發(fā)者都棄用多l(xiāng)ocale的GTK+1.2,我印象中至少經(jīng)歷了三到四年。BOM不受歡迎主要是在UNIX環(huán)境下,因?yàn)楹芏郩NIX程序不鳥BOM。主要問題出在UNIX那個(gè)所有腳本語言通行的首行#!標(biāo)示,這東西依賴于shell解析,而很多shell出于兼容的考慮不檢測(cè)BOM,所以加進(jìn)BOM時(shí)shell會(huì)把它解釋為某個(gè)普通字符輸入導(dǎo)致破壞#!標(biāo)示,這就麻煩了。其實(shí)很多現(xiàn)代腳本語言,比如Python,其解釋器本身都是能處理BOM的,但是shell卡在這里,沒辦法,只能躺著也中槍。說起來這也不能怪shell,因?yàn)锽OM本身違反了一個(gè)UNIX設(shè)計(jì)的常見原則,就是文檔中存在的數(shù)據(jù)必須可見。BOM不能作為可見字符被文本編輯器編輯,就這一條很多UNIX開發(fā)者就不滿意。順便說一句,即使腳本語言能處理BOM,隨處使用BOM也不是推薦的辦法。各個(gè)腳本語言對(duì)Unicode的處理都有自己的一套,Python的 # -- coding: utf-8 --,Perl的use utf8,都比BOM簡(jiǎn)單而且可靠。另一個(gè)好消息是,即使是必須在Windows和UNIX之間切換的朋友也不會(huì)悲催。幸虧在UNIX環(huán)境下我們還有VIM這種神器,即使遇到BOM擋道,我們也可以通過 set nobomb; set fileencoding=utf8; w 三條命令解決問題。最后回頭想想,似乎也真就只有Windows堅(jiān)持用BOM了。P.S.:本問題是自己的第150個(gè)回答。突然發(fā)現(xiàn)自己回答得很少很少??P.S. 2:突然想起需要解釋一下為什么說VIM去除bomb的操作需要在UNIX下完成。因?yàn)閂IM在Windows環(huán)境下有一個(gè)奇怪的bug,總是把UTF-16文件識(shí)別成二進(jìn)制文件,而UNIX(Linux或者M(jìn)ac都可以)下VIM則無問題。這個(gè)問題從VIM 6.8一直跟著我到VIM 7.3。目前尚不清楚這是VIM的bug還是我自己那個(gè).vimrc文件的bug。如有高手解答不勝感激。
@引用結(jié)束
總結(jié)
以下是一些經(jīng)典語錄:
- HTML有charset屬性,XML有encoding屬性,沒必要拉BOM撐場(chǎng)面
- UTF-16這種編碼連ASCII都雙字節(jié),實(shí)在不適用于做網(wǎng)頁
- 通常BOM是用來標(biāo)示Unicode純文本字節(jié)流的,讓文本處理程序識(shí)別txt文件是哪個(gè)Unicode編碼(UTF-8,UTF-16BE,UTF-16LE)
- Windows相對(duì)對(duì)BOM處理比較好, 打開文本文件時(shí)它會(huì)自動(dòng)識(shí)別并剔除BOM.
- Windows的設(shè)計(jì)者希望能在用戶不注意的情況下同時(shí)兼容Unicode和非Unicode(Multiple byte)文本文件.
- Linux一步到位進(jìn)入U(xiǎn)TF-8, 過渡期至少經(jīng)歷了三到四年.
- BOM不受歡迎主要是在UNIX環(huán)境下,因?yàn)楹芏郩NIX程序不鳥BOM。因?yàn)锽OM本身違反了一個(gè)UNIX設(shè)計(jì)的常見原則,就是文檔中存在的數(shù)據(jù)必須可見。
- UNIX環(huán)境下我們還有VIM這種神器,即使遇到BOM擋道,我們也可以通過 set nobomb; set fileencoding=utf8; w 三條命令解決問題。
- 似乎也真就只有Windows堅(jiān)持用BOM了。
- UTF-8不需要BOM, 所以不含BOM的UTF-8才是標(biāo)準(zhǔn)形式.
- 微軟在 UTF-8 中使用 BOM 是因?yàn)檫@樣可以把 UTF-8 和 ASCII 等編碼明確區(qū)分開
- UTF-8 的網(wǎng)頁代碼不應(yīng)使用 BOM,否則常常會(huì)出錯(cuò)
- 寫C++代碼建議程序要在windows 和 mac 還有l(wèi)inux 上運(yùn)行的話,源代碼最好保存成utf-8 帶bom的格式,這樣比較通用一些。而用utf-16 無論大端還是小端,g++ 都不認(rèn)的。或者用utf-8 不帶bom格式,然后代碼不要出現(xiàn)非ascii 127以后的字符。
- 帶用bom的utf-8也是符合國(guó)際標(biāo)準(zhǔn)的
- 微軟在堅(jiān)持使用bom上沒有錯(cuò),因?yàn)檫@是在為用戶考慮的。也許給我們這些寫程序的帶來了不便,但是,計(jì)算機(jī)最廣泛的用戶不是程序員。
- 帶頭的鵝和去頭的鵝,有些編輯器比較傻會(huì)把去頭的鵝認(rèn)成鴨子
- 以UTF-8格式編碼, 從notepad++ --> Mongodb里面復(fù)制東西的時(shí)候,莫名其妙多了不少的字節(jié)數(shù)。如果不安裝notepad++,使用默認(rèn)的記事本,那就更是個(gè)坑,默認(rèn)有bom,你還無法選擇。
- 就是因?yàn)檫@個(gè)bom,CSV導(dǎo)入mongodb時(shí),第一個(gè)字段總是不正常,直接導(dǎo)致用第一個(gè)字段作為條件find時(shí),出不了結(jié)果!
- utf8對(duì)ascii的兼容確實(shí)是它的好,但是這個(gè)優(yōu)點(diǎn)在某些時(shí)候恰恰成了隱藏問題的缺點(diǎn)。因此bom大法好,加bom保平安.
- 為什么windows的記事本要強(qiáng)行給utf8加bom的原因——為了兼容舊系統(tǒng)的編碼問題,unix陣營(yíng)放棄帶bom的utf8——為了讓它們的上古程序能繼續(xù)運(yùn)行下去,這個(gè)各自有自己利益訴求的差異決定其實(shí)并不對(duì)錯(cuò)
參考:
浙公網(wǎng)安備 33010602011771號(hào)