JavaSE--jdom解析之bom
參考:http://www.cnblogs.com/findumars/p/3620078.html
1 org.jdom2.input.JDOMParseException: Error on line 1: Content is not allowed in prolog. 2 13:15:55,821 [main] ERROR SajtSvrImpl:182 - 未知:org.jdom2.input.JDOMParseException: Error on line 1: Content is not allowed in prolog. 3 at org.jdom2.input.sax.SAXBuilderEngine.build(SAXBuilderEngine.java:232) 4 at org.jdom2.input.SAXBuilder.build(SAXBuilder.java:1065)
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 準備的,用于標記字節(jié)序(byte order)。微軟在 UTF-8 中使用 BOM 是因為這樣可以把 UTF-8 和 ASCII 等編碼明確區(qū)分開,但這樣的文件在 Windows 之外的操作系統(tǒng)里會帶來問題。
「UTF-8」和「帶 BOM 的 UTF-8」的區(qū)別就是有沒有 BOM。即文件開頭有沒有 U+FEFF。
UTF-8 的網(wǎng)頁代碼不應使用 BOM,否則常常會出錯。這是一個小例子: 為什么這個網(wǎng)頁代碼 <head> 內(nèi)的信息會被瀏覽器理解為在 <body> 內(nèi)?
另附《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.pdf
---------------------------------------------------------
首先,BOM是啥。這個就不解釋了,Wikipedia上很詳細。http://en.wikipedia.org/wiki/Byte_order_mark。
在網(wǎng)頁上使用BOM是個錯誤。BOM設(shè)計出來不是用來支持HTML和XML的。要識別文本編碼,HTML有charset屬性,XML有encoding屬性,沒必要拉BOM撐場面。雖然理論上BOM可以用來識別UTF-16編碼的HTML頁面,但實際工程上很少有人這么干。畢竟UTF-16這種編碼連ASCII都雙字節(jié),實在不適用于做網(wǎng)頁。
其實說BOM是個壞習慣也不盡然。BOM也是Unicode標準的一部分,有它特定的適用范圍。通常BOM是用來標示Unicode純文本字節(jié)流的,用來提供一種方便的方法讓文本處理程序識別讀入的.txt文件是哪個Unicode編碼(UTF-8,UTF-16BE,UTF-16LE)。Windows相對對BOM處理比較好,是因為Windows把Unicode識別代碼集成進了API里,主要是CreateFile()。打開文本文件時它會自動識別并剔除BOM。Windows用這個有歷史原因,因為它最初脫胎于多代碼頁的環(huán)境(ANSI環(huán)境)。而引入Unicode時Windows的設(shè)計者又希望能在用戶不注意的情況下同時兼容Unicode和非Unicode(Multiple byte)文本文件,就只能借助這種小trick了。相比之下,Linux這樣的系統(tǒng)在多l(xiāng)ocale的環(huán)境中浸染的時間比較短,再加上社區(qū)本身也有足夠的動力輕裝前進(吐槽:微軟對兼容性的要求確實是到了非常偏執(zhí)的地步,任何一點破壞兼容性的做法都不允許,以至于很多時候是自己綁住自己的雙手),所以干脆一步到位進入UTF-8。當然中間其實有一段過渡期,比如從最初全UTF-8的GTK+2.0發(fā)布到基本上所有GTK開發(fā)者都棄用多l(xiāng)ocale的GTK+1.2,我印象中至少經(jīng)歷了三到四年。
BOM不受歡迎主要是在UNIX環(huán)境下,因為很多UNIX程序不鳥BOM。主要問題出在UNIX那個所有腳本語言通行的首行#!標示,這東西依賴于shell解析,而很多shell出于兼容的考慮不檢測BOM,所以加進BOM時shell會把它解釋為某個普通字符輸入導致破壞#!標示,這就麻煩了。其實很多現(xiàn)代腳本語言,比如Python,其解釋器本身都是能處理BOM的,但是shell卡在這里,沒辦法,只能躺著也中槍。說起來這也不能怪shell,因為BOM本身違反了一個UNIX設(shè)計的常見原則,就是文檔中存在的數(shù)據(jù)必須可見。BOM不能作為可見字符被文本編輯器編輯,就這一條很多UNIX開發(fā)者就不滿意。
順便說一句,即使腳本語言能處理BOM,隨處使用BOM也不是推薦的辦法。各個腳本語言對Unicode的處理都有自己的一套,Python的 # -*- coding: utf-8 -*-,Perl的use utf8,都比BOM簡單而且可靠。另一個好消息是,即使是必須在Windows和UNIX之間切換的朋友也不會悲催。幸虧在UNIX環(huán)境下我們還有VIM這種神器,即使遇到BOM擋道,我們也可以通過 set nobomb; set fileencoding=utf8; w 三條命令解決問題。
最后回頭想想,似乎也真就只有Windows堅持用BOM了。
P.S.:本問題是自己的第150個回答。突然發(fā)現(xiàn)自己回答得很少很少??
P.S. 2:突然想起需要解釋一下為什么說VIM去除bomb的操作需要在UNIX下完成。因為VIM在Windows環(huán)境下有一個奇怪的bug,總是把UTF-16文件識別成二進制文件,而UNIX(Linux或者Mac都可以)下VIM則無問題。這個問題從VIM 6.8一直跟著我到VIM 7.3。目前尚不清楚這是VIM的bug還是我自己那個.vimrc文件的bug。如有高手解答不勝感激。
---------------------------------------------------------
有bom格式在開頭會多出3個字節(jié) EF BB BF ,主要用于識別編碼。bom應該是windows特有的,在制作網(wǎng)頁時會產(chǎn)生各種意想不到的問題,例如多輸出了一個空行,影響PHP的session或者cookies功能(出現(xiàn) header already sent錯誤),甚至可能引起頁面的亂碼(那3個字節(jié)影響了瀏覽器對頁面編碼的處理),因此總是推薦使用無bom編碼。為了處理這個問題我甚至寫了一個批量處理的PHP腳本。
---------------------------------------------------------
邸強,軟件開發(fā)ing
張旭東、Mingyue Zhou、sapjax 贊同
幾周前還在為BOM的問題苦惱著。。。
正如@梁海所說,“不含 BOM 的 UTF-8 才是標準形式”,的確是這樣,無BOM使用得更多些,所以個人還是推薦一般情況下用無BOM的形式吧,除非有問題的時候,再考慮換有BOM的。Windows系統(tǒng)保存的都是有BOM的,所以你可以看到,用記事本保存一個UTF-8的txt,其實是有BOM的,這一點需要注意。另外不同的文本編輯器對于有無BOM的稱呼也略有不同,比如EditPlus,有BOM的稱為UTF-8+,無BOM的稱為UTF-8,而在Notepad++中,有BOM的被稱為標準UTF-8,而無BOM則被稱為UTF-8無BOM。
---------------------------------------------------------
武龍飛,c/c++ 程序員,喜歡天文學,數(shù)學和心理學。
Weijing Huang、Bill Chan、icky R 贊同
以下文字出自我的博客內(nèi)容,從另一面解說不一樣的bom。
---------------------------------------------------------
字符編碼相信是每個程序員的噩夢,只要是有中文的地方,總是會遇到各種編碼的問題,并且這種問題還非常難纏,尤其在linux上,因為上面很多軟件都是針對英語國家開發(fā)的,是不會考慮其他語種編碼問題。在遇到編碼的無數(shù)大坑之后,我決定仔細研究下編碼問題,因為這就像一道坎一直橫在你面前,每次到這里你都會跌到,每次爬起來之后,你都若無其事,這樣的人被稱作戰(zhàn)士,真正的戰(zhàn)士。可惜是個力量戰(zhàn)士,做為新時代的智力戰(zhàn)士,當然不能在那跌到然后又在這繼續(xù)跌到。
文件的存儲方式:
文件都有自己的存儲格式,比如最常見的txt,cpp,h,c,xml ,png, rmvb各種格式,還有自定義格式。這些文件不論是什么格式,都是存儲在計算機硬盤里的2進制格存儲,對應不同文件格式,有不同的軟件解析。這篇文章不談文件是如何存儲的,只談文件是如何解析的。
文本文件解析:
文本文件對應于人類可以閱讀的文本,如何從2進制轉(zhuǎn)換為文本文件呢?起初由于計算機在美國發(fā)明,自然大家考慮的是英語如何表示,英語字母總共26個,加上特殊字符,128個字符,7位既一個byte即可表示出來。這個就是大家所熟知的ascill編碼。對應關(guān)系很簡單,一個字符對應一一個byte。
但很快發(fā)現(xiàn),其他非英語國家的文字遠遠超過ascill碼,這時候大家當然想統(tǒng)一一下,不同國家出了自己不同的編碼方式,中國的gb2312就是自己做出來的編碼方式,這樣下去每個國家都有自己的編碼方式,來回轉(zhuǎn)換太麻煩了。這時候出現(xiàn)了新的編碼方式,unicode編碼方式,想將編碼統(tǒng)一,所以規(guī)定了每個字符對應的unicode碼。
1、很多文件都是ascii編碼,如果用unicode 太浪費。
2、沒有標志位說明該幾個字節(jié)來解析為一個符號。
這時候拯救世界的utf出現(xiàn)了,utf是unicode的一種實現(xiàn),只不過更聰明了。utf16是占用兩字節(jié),或者四字節(jié),utf32是占用四字節(jié)。utf8是很聰明的一種表示方式。
1、對于單字節(jié)符號,字節(jié)第一位為0,后面7位表示字節(jié)編碼。
2、對于n字節(jié)符號,第一字節(jié)的前n位都設(shè)為1,第n+1位為0,其余位位編碼位置。
對于不同的編碼,在文本的最前方有不同的標志,unicode 通常有兩位來表示分別是ff fe, 或者feff, fffe表示big-endian 編碼feff表示litte-endian編碼。utf8是efbbbf來開頭的。可以看出來utf-8是自解釋的,所以不用帶這個標志文件,大多數(shù)程序是可以識別的。但有些程序不能識別這個標志,比如php就會直接把這個標志當文本解析,不會忽略。相信很多遇到php輸出文本解析亂碼或者解析錯誤的同學都遇到這樣的問題。
最后說說如何去掉或者加上bom,如果有vim那最好不過了,去掉命令:
set encoding=utf-8
set nobomb
添加命令:
set encoding=utf-8
set bomb
---------------------------------------------------------
帶 BOM 的 UTF-8 就是赤裸裸的流氓!!!!!!!!!
windows總是自做聰明的做一些別人無法理解的事情!!!UTF-8是不需要BOM頭的~~~!!
從剛開始學習代碼(實在不能稱我做的東西為程序)到現(xiàn)在,不曉得被這個BOM頭搞了多少次,特別是對于我這種完全自學的人,知道找一個BUG需要多久多久不????
帶不帶BOM頭區(qū)別就在于這個BOM頭,祥見排名靠前的大神答案。windows特有的奇葩。請使用UTF-8 不帶BOM頭!!
它產(chǎn)生的BUG包含但不僅限于:
锘 -- 感謝 @飛揚 提供,參考其答案
HTML空白行
div之間莫明的間隔
亂碼!
如果你用ssl那么一定會有問題!!!
順便再鄙視一下 SONY的記憶棒、IPHONE的接口~~
這種吐槽的東西就讓它折疊吧
--------------------------------------------------------
帶 BOM 的 UTF-8 非常操蛋,經(jīng)常造成莫名其妙的問題。
---------------------------------------------------------
我都是用的UTF-8 without BOM,帶BOM的經(jīng)常出現(xiàn)亂碼
---------------------------------------------------------
notepad++會自動添加為帶Bom的utf8比較坑爹
---------------------------------------------------------
建議編程人員能使用 Mac 編程的盡量使用Mac,Window是及其操蛋的操作系統(tǒng)。其次,如果我們要讀取三方的文件并以UTF-8格式解析的時候一定要注意去判斷這個文件是否有BOM,例如:sql文件的解析執(zhí)行。
---------------------------------------------------------
網(wǎng)頁編程中用不用bom我就不說什么了,因為軟件原因無法使用的就更不能用了。
最近在學習用cocos2d-x,純C++的編碼,如果代碼中有中文等的非ascii字符出現(xiàn)。發(fā)現(xiàn)會出錯。代碼是在mac 下用xcode 寫的,放到windows 下用vs 編譯。
最后把所有的源文件轉(zhuǎn)成了帶bom的格式后編譯通過了,鏈接失敗,這想這個就不是編碼的問題了。
通常情況下,一般都 會認為在寫C++代碼的時候不要用中文,但是很多時候我們程序員也有想自己看著舒服的時候,為神馬就不能寫中文了?
于是在windows 下寫了一個helloworld.cpp 類型的文件,輸出內(nèi)容用中文,然后存為utf-8 帶bom格式,再把它copy到mac 下用g++ 編譯,發(fā)現(xiàn)成功通過并且可正常運行,用xcode打開源文件也正常顯示。
所以,這里建議程序要在windows 和 mac 還有l(wèi)inux 上運行的話,源代碼最好保存成utf-8 帶bom的格式,這樣比較通用一些。而用utf-16 無論大端還是小端,g++ 都不認的。或者用utf-8 不帶bom格式,然后代碼不要出現(xiàn)非ascii 127以后的字符。
關(guān)于說utf-8 不帶bom 才是標準的,我想應該是帶用個人情緒的說法吧。真正的標準應該是bom是可選的,為什么可選?因為有些時候不帶bom會出錯,就拿歷史較久遠的windows來講吧,很多國家的用戶都在用windows ,其文件都是用其本地的ansi 編碼來做的,比如大陸的GBK和GB2013,港臺的big5,這些編碼因為針對當?shù)厮玫淖址贫ǖ?#xff0c;所以呢,其存儲文件較小,所以會大量使用,并且也大量存在著,微軟不可能不考慮全球幾十億的用戶的文件而盲目地修改解碼方式,并且微軟也是uncode 制定者之一,所以,帶用bom的utf-8也是符合國際標準的。
或許是因為程序編寫者的個人原因,也許是考慮到效率,很多的程序無法正確區(qū)分一個utf-8文件是否有bom,所以導致了各種亂碼的出現(xiàn)。
個人不想說哪個是標準,也不想用語言去攻擊哪個公司或團體。微軟在堅持使用bom上沒有錯,因為這是在為用戶考慮的。也許給我們這些寫程序的帶來了不便,但是,計算機最廣泛的用戶不是程序員。
---------------------------------------------------------
摘自:
http://www.zhihu.com/question/20167122
轉(zhuǎn)載于:https://www.cnblogs.com/microcat/p/7000606.html
總結(jié)
以上是生活随笔為你收集整理的JavaSE--jdom解析之bom的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 画一个圈是什么歌啊?
- 下一篇: 《长相思·九月西风兴》第十七句是什么