java读取utf8_java读取UTF-8的txt文件发现开头的一个字符问题

今天遇到一个奇葩问题,在读取一个TXT文件时,出现开头多了一个问号(?)。如下图:

aa930bbab20ed8e18f8688496e7f4885.png

莫名奇妙的多了一个。最后通过网上资料,知道在Java中,class文件采用utf8的编码方式,JVM运行时采用utf16。Java的字符串是永远都是unicode的,采用的是UTF-16的编码方式。

想测试一下,java对UTF-8文件的读写的能力,结果发现了一个很郁闷的问题,如果通过java写的UTF-8文件,使用Java可以正确的读,但是如果用记事本将相同的内容使用UTF-8格式保存,则在使用程序读取是会从文件中多读出一个不可见字符。

测试代码如下:

Java代码  85f89255289a1d8d8aaba9b32f3746cc.png

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();

}

}

}

save_snippets.png

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.保存时,选择

9f3a9260b07a54438823a5c20e910b5a.png

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

ps:贴一下读取的工具类源码:

1 /**

2 * 读入文件到字串中3 *4 *@paramfile 需要读取的文件路径5 *@return读取的文件内容,若读入失败,则返回空字串6 */

7 public staticString 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(newFile(file), encoding);16 returncontent;17 }18 catch(IOException ex)19 {20 logger.error("读取文件出错", ex);21 }22 return "";23 }

注意两点都要过一下,希望有用。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值