Java處理文件BOM頭的方式推薦


背景:

java普通的文件讀取方式對於bom是無法正常識別的。

   使用普通的InputStreamReader,如果采用的編碼正確,那么可以獲得正確的字符,但bom仍然附帶在結果中,很容易導致數據處理出錯。
另外,對於存在BOM頭的文件,無法猜測它使用的編碼。

目標:

實現一種方式,可對BOM頭進行捕捉和過濾

 

解決方案有二:

一、  使用apache的工具類,以BOMStream為例:

    BOMStream,api參考:http://commons.apache.org/io/apidocs/org/apache/commons/io/input/BOMInputStream.html

   該類的構造方式:
   BOMInputStream bomIn = new BOMInputStream(in) //僅能檢測到UTF8的bom,且在流中exclude掉bom
   
   BOMInputStream bomIn = new BOMInputStream(in, include); //同上,且指定是否包含

   也可以指定檢測多種編碼的bom,但目前僅支持UTF-8/UTF-16LE/UTF-16BE三種,對於UTF32之類不支持。
   BOMInputStream bomIn = new BOMInputStream(in, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE);
   
   有用的方法:
   bomIn.hasBOM()、hasBOM(ByteOrderMask.**)可用於判斷當前流中是否檢測到了bom。

   讀取文件示例:

FileInputStream fis = new FileInputStream(file);  
  //可檢測多種類型,並剔除bom  
  BOMInputStream bomIn = new BOMInputStream(in, false,ByteOrderMark.UTF-8, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE);  
  String charset = "utf-8";  
  //若檢測到bom,則使用bom對應的編碼  
  if(bomIn.hasBOM()){  
     charset = bomIn.bs.getBOMCharsetName();  
  }  
  InputStreamReader reader = new InputStreamReader(bomIn, charset);  
  ...  


二、使用一個更強大點的工具類(可以支持UTF-8/UTF-16LE/UTF-16BE/UTF-32LE/UTF-32BE):
       

   參考地址:http://koti.mbnet.fi/akini/java/unicodereader/, 下載其中兩個文件:UnicodeStream和UnicodeReader

   以UnicodeReader為例:

FileInputStream fis = new FileInputStream(file);  
UnicodeReader ur = new UnicodeReader(fis, "utf-8");  
BufferedReader br = new BufferedReader(ur);  
...  

 

   相較於Apache的工具類,這里的UnicodeReader 支持更多的BOM編碼。

   源碼解讀:

   UnicodeReader 通過PushbackInputStream+InputStreamReader實現BOM的自動檢測和過濾讀取;

   當沒有檢測到BOM時,pushback流將回退,並采用構造函數傳入的編碼進行讀取。
   否則使用BOM對應的編碼進行讀取。

   

  相對來說,第二種方式更加輕量和強大;另外也更加透明,可以隨便修改源碼來實現自己的需求。


免責聲明!

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



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