UTF-8 不須要 BOM,儘管 Unicode 標準容許在 UTF-8 中使用 BOM。
因此不含 BOM 的 UTF-8 纔是標準形式,在 UTF-8 文件中放置 BOM 主要是微軟的習慣(順便提一下:把帶有 BOM 的小端序 UTF-16 稱做「Unicode」而又不詳細說明,這也是微軟的習慣)。
BOM(byte order mark)是爲 UTF-16 和 UTF-32 準備的,用於標記字節序(byte order)。微軟在 UTF-8 中使用 BOM 是由於這樣能夠把 UTF-8 和 ASCII 等編碼明確區分開,但這樣的文件在 Windows 以外的操做系統裏會帶來問題。php
「UTF-8」和「帶 BOM 的 UTF-8」的區別就是有沒有 BOM。即文件開頭有沒有 U+FEFF。
UTF-8 的網頁代碼不該使用 BOM,不然經常會出錯。這是一個小例子: 爲何這個網頁代碼 <head> 內的信息會被瀏覽器理解爲在 <body> 內?linux
另附《The Unicode Standard, Version 6.0》之 3.10 D95 UTF-8 encoding scheme 的一段話:
While there is obviously no need for a byte order signature when using UTF-8, there are occasions when processes convert UTF-16 or UTF-32 data containing a byte order mark into UTF-8. When represented in UTF-8, the byte order mark turns into the byte sequence. Its usage at the beginning of a UTF-8 data stream is neither required nor recommended by the Unicode Standard, but its presence does not affect conformance to the UTF-8 encoding scheme. Identification of the byte sequence at the beginning of a data stream can, however, be taken as a near-certain indication that the data stream is using the UTF-8 encoding scheme.
http://www.unicode.org/versions/Unicode6.0.0/ch03.pdfc++
---------------------------------------------------------
首先,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用這個有歷史緣由,由於它最初脫胎於多代碼頁的環境(ANSI環境)。而引入Unicode時Windows的設計者又但願能在用戶不注意的狀況下同時兼容Unicode和非Unicode(Multiple byte)文本文件,就只能藉助這種小trick了。相比之下,Linux這樣的系統在多locale的環境中浸染的時間比較短,再加上社區自己也有足夠的動力輕裝前進(吐槽:微軟對兼容性的要求確實是到了很是偏執的地步,任何一點破壞兼容性的作法都不容許,以致於不少時候是本身綁住本身的雙手),因此乾脆一步到位進入UTF-8。固然中間其實有一段過渡期,好比從最初全UTF-8的GTK+2.0發佈到基本上全部GTK開發者都棄用多locale的GTK+1.2,我印象中至少經歷了三到四年。sql
BOM不受歡迎主要是在UNIX環境下,由於不少UNIX程序不鳥BOM。主要問題出在UNIX那個全部腳本語言通行的首行#!標示,這東西依賴於shell解析,而不少shell出於兼容的考慮不檢測BOM,因此加進BOM時shell會把它解釋爲某個普通字符輸入致使破壞#!標示,這就麻煩了。其實不少現代腳本語言,好比Python,其解釋器自己都是能處理BOM的,可是shell卡在這裏,沒辦法,只能躺着也中槍。提及來這也不能怪shell,由於BOM自己違反了一個UNIX設計的常見原則,就是文檔中存在的數據必須可見。BOM不能做爲可見字符被文本編輯器編輯,就這一條不少UNIX開發者就不滿意。shell
順便說一句,即便腳本語言能處理BOM,隨處使用BOM也不是推薦的辦法。各個腳本語言對Unicode的處理都有本身的一套,Python的 # -*- coding: utf-8 -*-,Perl的use utf8,都比BOM簡單並且可靠。另外一個好消息是,即便是必須在Windows和UNIX之間切換的朋友也不會悲催。幸好在UNIX環境下咱們還有VIM這種神器,即便遇到BOM擋道,咱們也能夠經過 set nobomb; set fileencoding=utf8; w 三條命令解決問題。編程
最後回頭想一想,彷佛也真就只有Windows堅持用BOM了。vim
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。若有高手解答不勝感激。windows
---------------------------------------------------------xcode
有bom格式在開頭會多出3個字節 EF BB BF ,主要用於識別編碼。bom應該是windows特有的,在製做網頁時會產生各類意想不到的問題,例如多輸出了一個空行,影響PHP的session或者cookies功能(出現 header already sent錯誤),甚至可能引發頁面的亂碼(那3個字節影響了瀏覽器對頁面編碼的處理),所以老是推薦使用無bom編碼。爲了處理這個問題我甚至寫了一個批量處理的PHP腳本。
---------------------------------------------------------
邸強,軟件開發ing
張旭東、Mingyue Zhou、sapjax 贊同
幾周前還在爲BOM的問題苦惱着。。。
正如@梁海所說,「不含 BOM 的 UTF-8 纔是標準形式」,的確是這樣,無BOM使用得更多些,因此我的仍是推薦通常狀況下用無BOM的形式吧,除非有問題的時候,再考慮換有BOM的。Windows系統保存的都是有BOM的,因此你能夠看到,用記事本保存一個UTF-8的txt,實際上是有BOM的,這一點須要注意。另外不一樣的文本編輯器對於有無BOM的稱呼也略有不一樣,好比EditPlus,有BOM的稱爲UTF-8+,無BOM的稱爲UTF-8,而在Notepad++中,有BOM的被稱爲標準UTF-8,而無BOM則被稱爲UTF-8無BOM。
---------------------------------------------------------
武龍飛,c/c++ 程序員,喜歡天文學,數學和心理學。
Weijing Huang、Bill Chan、icky R 贊同
如下文字出自個人博客內容,從另外一面解說不同的bom。
---------------------------------------------------------
字符編碼相信是每一個程序員的噩夢,只要是有中文的地方,老是會遇到各類編碼的問題,而且這種問題還很是難纏,尤爲在linux上,由於上面不少軟件都是針對英語國家開發的,是不會考慮其餘語種編碼問題。在遇到編碼的無數大坑以後,我決定仔細研究下編碼問題,由於這就像一道坎一直橫在你面前,每次到這裏你都會跌到,每次爬起來以後,你都若無其事,這樣的人被稱做戰士,真正的戰士。惋惜是個力量戰士,作爲新時代的智力戰士,固然不能在那跌到而後又在這繼續跌到。
文件的存儲方式:
文件都有本身的存儲格式,好比最多見的txt,cpp,h,c,xml ,png, rmvb各類格式,還有自定義格式。這些文件不管是什麼格式,都是存儲在計算機硬盤裏的2進制格存儲,對應不一樣文件格式,有不一樣的軟件解析。這篇文章不談文件是如何存儲的,只談文件是如何解析的。
文本文件解析:
文本文件對應於人類能夠閱讀的文本,如何從2進制轉換爲文本文件呢?起初因爲計算機在美國發明,天然你們考慮的是英語如何表示,英語字母總共26個,加上特殊字符,128個字符,7位既一個byte便可表示出來。這個就是你們所熟知的ascill編碼。對應關係很簡單,一個字符對應一一個byte。
但很快發現,其餘非英語國家的文字遠遠超過ascill碼,這時候你們固然想統一一下,不一樣國家出了本身不一樣的編碼方式,中國的gb2312就是本身作出來的編碼方式,這樣下去每一個國家都有本身的編碼方式,來回轉換太麻煩了。這時候出現了新的編碼方式,unicode編碼方式,想將編碼統一,因此規定了每一個字符對應的unicode碼。
一、不少文件都是ascii編碼,若是用unicode 太浪費。
二、沒有標誌位說明該幾個字節來解析爲一個符號。
這時候拯救世界的utf出現了,utf是unicode的一種實現,只不過更聰明瞭。utf16是佔用兩字節,或者四字節,utf32是佔用四字節。utf8是很聰明的一種表示方式。
一、對於單字節符號,字節第一位爲0,後面7位表示字節編碼。
二、對於n字節符號,第一字節的前n位都設爲1,第n+1位爲0,其他位位編碼位置。
對於不一樣的編碼,在文本的最前方有不一樣的標誌,unicode 一般有兩位來表示分別是ff fe, 或者feff, fffe表示big-endian 編碼feff表示litte-endian編碼。utf8是efbbbf來開頭的。能夠看出來utf-8是自解釋的,因此不用帶這個標誌文件,大多數程序是能夠識別的。但有些程序不能識別這個標誌,好比php就會直接把這個標誌當文本解析,不會忽略。相信不少遇到php輸出文本解析亂碼或者解析錯誤的同窗都遇到這樣的問題。
最後說說如何去掉或者加上bom,若是有vim那最好不過了,去掉命令:
set encoding=utf-8
set nobomb
添加命令:
set encoding=utf-8
set bomb
---------------------------------------------------------
帶 BOM 的 UTF-8 就是赤裸裸的流氓!!!!!!!!!
windows老是自作聰明的作一些別人沒法理解的事情!!!UTF-8是不須要BOM頭的~~~!!
從剛開始學習代碼(實在不能稱我作的東西爲程序)到如今,不曉得被這個BOM頭搞了多少次,特別是對於我這種徹底自學的人,知道找一個BUG須要多久多久不????
帶不帶BOM頭區別就在於這個BOM頭,祥見排名靠前的大神答案。windows特有的奇葩。請使用UTF-8 不帶BOM頭!!
它產生的BUG包含但不只限於:
鍩 -- 感謝 @飛揚 提供,參考其答案
HTML空白行
div之間莫明的間隔
亂碼!
若是你用ssl那麼必定會有問題!!!
順便再鄙視一下 SONY的記憶棒、IPHONE的接口~~
這種吐槽的東西就讓它摺疊吧
--------------------------------------------------------
帶 BOM 的 UTF-8 很是操蛋,常常形成莫名其妙的問題。
---------------------------------------------------------
我都是用的UTF-8 without BOM,帶BOM的常常出現亂碼
---------------------------------------------------------
notepad++會自動添加爲帶Bom的utf8比較坑爹
---------------------------------------------------------
建議編程人員能使用 Mac 編程的儘可能使用Mac,Window是及其操蛋的操做系統。其次,若是咱們要讀取三方的文件並以UTF-8格式解析的時候必定要注意去判斷這個文件是否有BOM,例如:sql文件的解析執行。
---------------------------------------------------------
網頁編程中用不用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,這些編碼由於針對當地所用的字符制定的,因此呢,其存儲文件較小,因此會大量使用,而且也大量存在着,微軟不可能不考慮全球幾十億的用戶的文件而盲目地修改解碼方式,而且微軟也是uncode 制定者之一,因此,帶用bom的utf-8也是符合國際標準的。
或許是由於程序編寫者的我的緣由,也許是考慮到效率,不少的程序沒法正確區分一個utf-8文件是否有bom,因此致使了各類亂碼的出現。
我的不想說哪一個是標準,也不想用語言去攻擊哪一個公司或團體。微軟在堅持使用bom上沒有錯,由於這是在爲用戶考慮的。也許給咱們這些寫程序的帶來了不便,可是,計算機最普遍的用戶不是程序員。---------------------------------------------------------摘自:http://www.zhihu.com/question/20167122