天天看點

UTF8格式中的BOM問題

昨天在編寫程式過程中碰到一個問題,分詞元件在加載詞典時(詞典檔案是以UTF-8格式儲存的txt檔案),詞典裡的第一個詞卻找不到;跟蹤進去後發現在加載詞典時,第一個詞的長度莫名的變長了一位,當時以為是帶有空格或換行符,加了trim操作和去換行符,測試後問題依舊;

後來在網上google了一下,最終發現問題是由于Utf-8編碼格式的檔案所導緻,如果Utf-8的檔案被記事本、DW工具編輯過,但沒有注意處理的方式,那麼會自動在Utf-8檔案中添加BOM格式,以表示檔案是Utf-8編碼的檔案。

unicode編碼為65279的字元叫“ZERO WIDTH NO-BREAK SPACE”即沒有寬度的空格符,本質上也是null值,但是不同于null。byte-order mark(BOM)是位于碼點U+FEFF的統一碼字元的名稱。當以UTF-16或UTF-32來将UCS/統一碼字元所組成的字元串編碼時,這個字元被用來标示其位元組序。它常被用來當做标示檔案是以UTF-8、UTF-16或UTF-32編碼的記号。說白了就是位于文本最前面用來辨別該unicode編碼的文本内容是以UTF-8、UTF-16或UTF-32編碼的。通過查詢發現windows的記事本程式在打開文本内容後會自動添加BOM。(這部分摘自http://lwjlaser.iteye.com/blog/1319220)

是以,在編輯、更改任何文本檔案時,請務必使用不會亂加BOM的編輯器。Linux下的編輯器應該都沒有這個問題。WINDOWS下,請勿使用記事本等編輯器。推薦的編輯器是: Editplus 2.12版本以上; EmEditor; UltraEdit(需要取消‘添加BOM’的相關選項); Dreamweaver(需要取消‘添加BOM’的相關選項) 等。

對于已經添加了BOM的檔案,要取消的話,可以用以上編輯器另存一次。(Editplus需要先另存為gb,再另存為UTF-8。)

DW解決辦法如下:

用DW打開指定檔案,按Ctrl+J->标題/編碼->編碼選擇“UTF-8”,去掉"包括Unicode簽名(BOM)"勾選->儲存/另存為,即可!

或者另外一種辦法就是在程式中讀取檔案時做下判斷,看是否需要去掉第一行的第一個char,代碼如下:

InputStreamReader FS = new InputStreamReader(in, "UTF-8");

BufferedReader SR = new BufferedReader(FS); // 檔案輸入流為

String strLine = SR.readLine();

if (strLine.length()>1){

if ((int)strLine.charAt(0)==65279){

strLine=strLine.substring(1);

}

}