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
相关文章
相关标签/搜索