今天遇到一個奇葩問題,在讀取一個TXT文件時,出現開頭多了一個問號(?)。以下圖:java
莫名奇妙的多了一個。最後經過網上資料,知道在Java中,class文件採用utf8的編碼方式,JVM運行時採用utf16。Java的字符串是永遠都是unicode的,採用的是UTF-16的編碼方式。
想測試一下,java對UTF-8文件的讀寫的能力,結果發現了一個很鬱悶的問題,若是經過java寫的UTF-8文件,使用Java能夠正確的讀,可是若是用記事本將相同的內容使用UTF-8格式保存,則在使用程序讀取是會從文件中多讀出一個不可見字符。apache
測試代碼以下:工具
utf.txt經過記事本建立,另存時使用指定utf-8編碼,其內容爲:測試
正常的測試結果應該是直接輸出utf.txt的文本內容。但是實際上卻輸出了下面的內容:編碼
第一行多出了一個問號。
經過上面的幾篇文章應該能夠想到是Java讀取BOM(Byte Order Mark)的問題,在使用UTF-8時,能夠在文件的開始使用3個字節的"EF BB BF"來標識文件使用了UTF-8的編碼,固然也能夠不用這個3個字節。
上面的問題應該就是由於對開頭3個字節的讀取致使的。開始不太相信這個是JDK的Bug,後來在屢次試驗後,問題依然存在,就又狗狗了一下,果真找到一個以下的Bug:
不過在我關掉的一些頁面中記得有篇文件說這個bug只在jdk1.5及以前的版本纔有,說是1.6已經解決了,從目前來看1.6只是解決了讀取帶有BOM文件失敗的問題,仍是不能區別處理有BOM和無BOM的UTF-8編碼的文件,從Bug ID:4508058裏的描述能夠看出,這個問題將做爲一個不會修改的問題關閉,對於BOM編碼的識別將由應用程序本身來處理,緣由可從另處一個bug處查看到,由於Unicode對於BOM的編碼的規定可能發生變化。也就是說對於一個UTF-8的文件,應用程序須要知道這個文件有沒有寫BOM,而後本身決定處理BOM的方式。spa
解決辦法:.net
1.保存時,選擇3d
2.引用正確的讀取類,好比我用的就是:org.apache.commons.io.FileUtils.readFileToString(new File(file), encoding);code
ps:貼一下讀取的工具類源碼:blog
1 /** 2 * 讀入文件到字串中 3 * 4 * @param file 須要讀取的文件路徑 5 * @return 讀取的文件內容,若讀入失敗,則返回空字串 6 */ 7 public static String readFileToString(String file, String encoding) 8 { 9 try 10 { 11 if (StringHelper.isEmpty(encoding)) 12 { 13 encoding = "GBK"; 14 } 15 String content = org.apache.commons.io.FileUtils.readFileToString(new File(file), encoding); 16 return content; 17 } 18 catch (IOException ex) 19 { 20 logger.error("讀取文件出錯", ex); 21 } 22 return ""; 23 }
注意兩點都要過一下,但願有用。