Java讀取Unicode文件(UTF-8等)時碰到的BOM首字符問題

在Windows下用文本編輯器建立的文本文件,若是選擇以UTF-8等Unicode格式保存,會在文件頭(第一個字符)加入一個BOM標識。
 
這個標識在Java讀取文件的時候,不會被去掉,並且String.trim()也沒法刪除。若是用readLine()讀取第一行存進String裏面,這個String的length會比看到的大1,並且第一個字符就是這個BOM。
 
這種狀況會形成一些麻煩,好比在讀取ini文件的時候,若是想判斷第一行是否是以「[」開頭就沒法正確判斷。
 
幸虧,Java在讀取Unicode文件的時候,會統一把BOM變成「\uFEFF」,這樣的話,就能夠本身手動解決了(判斷後,用substring()或replace()去除掉這個BOM):
[java]  view plain  copy
 
  1. if(line.startsWith("\uFEFF")){  
  2.  //line = line.substring(1);  
  3.  line = line.replace("\uFEFF", "");  
  4. }  
 
然而,這種方法並非完美的,若是生成jar文件在windows下運行,仍是有問題。終極的解決方法是使用apache commons io提供的BOMInputStream:
[html]  view plain  copy
 
  1. <dependency>  
  2.     <groupId>commons-io</groupId>  
  3.     <artifactId>commons-io</artifactId>  
  4.     <version>2.4</version>  
  5. </dependency>  

[java]  view plain  copy
 
  1. BufferedReader reader = null;  
  2.        try {  
  3.            //reader = new BufferedReader(new FileReader(file));  
  4.           
  5.         //使用BOMInputStream自動去除UTF-8中的BOM!!!  
  6.         reader = new BufferedReader(new InputStreamReader(new BOMInputStream(new FileInputStream(file))));  
  7.   
  8.         String str = null;  
  9.            //一次讀入一行(非空),直到讀入null爲文件結束  
  10.            while ((str = reader.readLine()) != null) {  
  11.            }  
 
什麼是BOM?
BOM = Byte Order Mark
BOM是Unicode規範中推薦的標記字節順序的方法。好比說對於UTF-16,若是接收者收到的BOM是FEFF,代表這個字節流是Big-Endian的;若是收到FFFE,就代表這個字節流是Little-Endian的。
UTF-8不須要BOM來代表字節順序,但能夠用BOM來代表「我是UTF-8編碼」。BOM的UTF-8編碼是EF BB BF(用UltraEdit打開文本、切換到16進制能夠看到)。因此若是接收者收到以EF BB BF開頭的字節流,就知道這是UTF-8編碼了。
 
全部的BOM在C/C++/Java中都被處理爲"\uFEFF"(???貌似不必定。。。),參考: http://www.fileformat.info/info/unicode/char/feff/index.htm
 
Wikipedia關於POM的說明介紹:
 
轉載自Clement-Xu的csdn博客。 https://blog.csdn.net/ClementAD/article/details/47168573
相關文章
相關標籤/搜索