java讀取UTF-8的txt文件發現開頭的一個字符問題

今天遇到一個奇葩問題,在讀取一個TXT文件時,出現開頭多了一個問號(?)。以下圖:java

莫名奇妙的多了一個。最後經過網上資料,知道在Java中,class文件採用utf8的編碼方式,JVM運行時採用utf16。Java的字符串是永遠都是unicode的,採用的是UTF-16的編碼方式。

測試一下,java對UTF-8文件的讀寫的能力,結果發現了一個很鬱悶的問題,若是經過java寫的UTF-8文件,使用Java能夠正確的讀,可是若是用記事本將相同的內容使用UTF-8格式保存,則在使用程序讀取是會從文件中多讀出一個不可見字符。apache

測試代碼以下:工具

Java代碼   收藏代碼
  1. import java.io.BufferedReader;  
  2. import java.io.File;  
  3. import java.io.FileInputStream;  
  4. import java.io.IOException;  
  5. import java.io.InputStreamReader;  
  6.   
  7.   
  8. public class UTF8Test {  
  9.     public static void main(String[] args) throws IOException {  
  10.         File f  = new File("./utf.txt");  
  11.         FileInputStream in = new FileInputStream(f);  
  12.         // 指定讀取文件時以UTF-8的格式讀取  
  13.         BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));  
  14.           
  15.         String line = br.readLine();  
  16.         while(line != null)  
  17.         {  
  18.             System.out.println(line);  
  19.             line = br.readLine();  
  20.         }  
  21.     }  
  22. }  



utf.txt經過記事本建立,另存時使用指定utf-8編碼,其內容爲:測試

引用

This is the first line.
This is second line.



正常的測試結果應該是直接輸出utf.txt的文本內容。但是實際上卻輸出了下面的內容:編碼

引用

?This is the first line.
This is second line.


第一行多出了一個問號。
經過上面的幾篇文章應該能夠想到是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     }

注意兩點都要過一下,但願有用。

相關文章
相關標籤/搜索