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


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

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

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

測試代碼如下:

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的方式。

解決辦法:

1.保存時,選擇

2.引用正確的讀取類,比如我用的就是:org.apache.commons.io.FileUtils.readFileToString(new File(file), encoding);

ps:貼一下讀取的工具類源碼:

 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     }

注意兩點都要過一下,希望有用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM