Java读带有BOM的UTF-8文件乱码原因及解决方法
来源:互联网 发布:ubuntu find命令 编辑:程序博客网 时间:2024/05/21 17:19
最近项目配置文件使用ini文件,并且使用UTF-8编码,当使用微软编辑器修改后会出现java读取乱码问题。后经调试发现是微软在修改UTF-8格式文件时会在文件开始添加BOM,三个字节字符,所以找到此解决方法。
测试代码如下:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class UTF8Test {
public static void main(String[] args) throws IOException {
File f = new File("./utf.txt");
FileInputStream in = new FileInputStream(f);
// 指定读取文件时以UTF-8的格式读取
BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
String line = br.readLine();
while(line != null)
{
System.out.println(line);
line = br.readLine();
}
}
}
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 ID:4508058
不过在我关掉的一些页面中记得有篇文件说这个bug只在jdk1.5及之前的版本才有,说是1.6已经解决了,从目前来看1.6只是解决了读取带有BOM文件失败的问题,还是不能区别处理有BOM和无BOM的UTF-8编码的文件,从Bug ID:4508058里的描述可以看出,这个问题将作为一个不会修改的问题关闭,对于BOM编码的识别将由应用程序自己来处理,原因可从另处一个bug处查看到,因为Unicode对于BOM的编码的规定可能发生变化。也就是说对于一个UTF-8的文件,应用程序需要知道这个文件有没有写BOM,然后自己决定处理BOM的方式。
在上面的while循环中可加入下面的代码,测试一下读出内容:
byte[] allbytes = line.getBytes("UTF-8");
for (int i=0; i < allbytes.length; i++)
{
int tmp = allbytes[i];
String hexString = Integer.toHexString(tmp);
// 1个byte变成16进制的,只需要2位就可以表示了,取后面两位,去掉前面的符号填充
hexString = hexString.substring(hexString.length() -2);
System.out.print(hexString.toUpperCase());
System.out.print(" ");
}
输出结果如下:
引用
EF BB BF 54 68 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74 20 6C 69 6E 65 2E
?This is the first line.
54 68 69 73 20 69 73 20 73 65 63 6F 6E 64 20 6C 69 6E 65 2E
This is second line.
红色部分的"EF BB BF"刚好是UTF-8文件的BOM编码,可以看出Java在读文件时没能正确处理UTF-8文件的BOM编码,将前3个字节当作文本内容来处理了。
使用链接中提供的代码可以解决碰到的乱码问题:http://koti.mbnet.fi/akini/java/unicodereader/
修改测试代码中的输入流后:
BufferedReader br = new BufferedReader(new UnicodeReader(in, Charset.defaultCharset().name()));
执行,可以看到正确的结果。
将用到的测试代码及UTF-8读取乱码解决的源码放在了附件中
免费下载地址在 http://linux.linuxidc.com/
用户名与密码都是www.linuxidc.com
具体下载目录在 /2012年资料/12月/23/Java读带有BOM的UTF-8文件乱码原因及解决方法
本篇文章来源于 Linux公社网站(www.linuxidc.com) 原文链接:http://www.linuxidc.com/Linux/2012-12/76707.htm
- Java读带有BOM的UTF-8文件乱码原因及解决方法
- Java读带有BOM的UTF-8文件乱码原因及解决方法
- Java读带有BOM的UTF-8文件乱码原因及解决方法
- Java读带有BOM的UTF-8文件乱码原因及解决方法
- Java读取UTF-8格式txt文件第一行出现乱码——问号“?”及解决;Java读带有BOM的UTF-8文件乱码原因及解决方法
- Java读取UTF-8格式txt文件第一行出现乱码——问号“?”及解决;Java读带有BOM的UTF-8文件乱码原因及解决方法
- Java读取UTF-8格式txt文件第一行出现乱码——问号“?”及解决;Java读带有BOM的UTF-8文件乱码原因及解决方法
- Java读取UTF-8格式txt文件第一行出现乱码——问号“?”及解决;Java读带有BOM的UTF-8文件乱码原因及解决方法
- Java读取UTF-8格式txt文件第一行出现乱码——问号“?”及解决;Java读带有BOM的UTF-8文件乱码原因及解决方法
- Java读取UTF-8格式txt文件第一行出现乱码——问号“?”及解决;Java读带有BOM的UTF-8文件乱码原因及解决方法
- Java读取UTF-8格式txt文件第一行出现乱码——问号“?”及解决;Java读带有BOM的UTF-8文件乱码原因及解决方法
- Java读取UTF-8格式txt文件第一行出现乱码——问号“?”及解决;Java读带有BOM的UTF-8文件乱码原因及解决方法
- Java读取UTF-8格式文件第一行出现乱码——问号“?”及解决 And Java读带有BOM的UTF-8文件乱码原因及解决方法
- Java读取带有BOM的UTF-8文件乱码原因及解决办法
- 读取文本出现 锘 * 系列乱码错误(UTF-8 BOM问题)的原因及解决方法
- 替换Java文件的utf-8 BOM
- response乱码 response.setCharacterEncoding("UTF-8")不生效的原因及解决方法
- java中文乱码的原因及解决方法
- 升级kindeditor 4.1.10 解决ie-11 相关bug 问题
- Arm汇编 位置无关代码 adr 指令
- 放开我们追梦的翅膀——致所有无私的父母
- signal 9
- C#导出数据到excel
- Java读带有BOM的UTF-8文件乱码原因及解决方法
- 容器,Map对象的遍历方法,HashMap与TreeMap区别,Vector、ArrayList、LinkedList区别
- [IOS开发教程] NSDate 日期操作工具类
- 字符,字节和编码
- 如何在工作中做到游刃有余?
- 添加TextView隐藏进度条的方法
- Week4-3Classic parsing methods
- 程序员偷偷深爱的 9 个不良编程习惯—兄弟连IT教育
- C++ 中cin用法