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

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

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

测试代码如下:

  1. import java.io.BufferedReader;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.IOException;
  5. import java.io.InputStreamReader;
  6. public class UTF8Test {
  7. public static void main(String[] args) throws IOException {
  8. File f  = new File("./utf.txt");
  9. FileInputStream in = new FileInputStream(f);
  10. // 指定读取文件时以UTF-8的格式读取
  11. BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
  12. String line = br.readLine();
  13. while(line != null)
  14. {
  15. System.out.println(line);
  16. line = br.readLine();
  17. }
  18. }
  19. }

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

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

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

 /**
* 读入文件到字串中
*
* @param file 需要读取的文件路径
* @return 读取的文件内容,若读入失败,则返回空字串
*/
public static String readFileToString(String file, String encoding)
{
try
{
if (StringHelper.isEmpty(encoding))
{
encoding = "GBK";
}
String content = org.apache.commons.io.FileUtils.readFileToString(new File(file), encoding);
return content;
}
catch (IOException ex)
{
logger.error("读取文件出错", ex);
}
return "";
}

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

java读取UTF-8的txt文件发现开头的一个字符问题的更多相关文章

  1. java将数据写入到txt文件中(txt有固定的格式)

    java将数据写入到txt文件中,这个应该对于学过java I/O的人来说是很简单的事情了,但是如果要将数据以固定的格式写入到txt文件中,就需要一定的技巧了. 这里举个简单的例子,以供参考: 比如我 ...

  2. C# 读取大文件 (可以读取3GB大小的txt文件)

    原文:C# 读取大文件 (可以读取3GB大小的txt文件) 在处理大数据时,有可能 会碰到 超过3GB大小的文件,如果通过 记事本 或 NotePad++去打开它,会报错,读不到任何文件. 如果你只是 ...

  3. 关于Java里面File类创建txt文件重复???

    private JButton getOpenButton() { if (openButton == null) { openButton = new JButton(); openButton.s ...

  4. java读取resource/通过文件名获取文件类型

    java读取resource java读取resource目录下文件的方法: 借助Guava库的Resource类 Resources.getResource("test.txt" ...

  5. 【转】Java读取matlab的.mat数据文件

    参考:Java读取mat文件 下载链接:ujmp  jmatio 下载完两个.jar文件之后,如何引用到java项目当中?项目名称->右键->Property->Java Build ...

  6. Java导出List集合到txt文件中——(四)

    有时候,需要将数据以一定格式导出到txt文件中.利用Java的IO可以轻松的导出数据到txt中. package Action.txt; import java.io.BufferedWriter; ...

  7. 解决:java 读取 resources 下面的 json 文件

    前言:java 读取 工程下的配置文件,文件类型为 json(*.json),记录一下始终读取不到 json 文件的坑.maven项目 直接上工具类代码 package com.yule.compon ...

  8. java存储数据到本地txt文件中

    java存储数据,方便打印日志等 1.会覆盖以前的数据 try { File writeName = new File("D:\\data.txt"); // 相对路径,如果没有则 ...

  9. java读取jar包中的文件

    随手写了一个java小工具,maven打包成功后,发现工具总是读不到打在jar包中的文件信息,要读取的文件位于 /src/main/resources 目录下,打包成功后,文件就在jar包中根目录下, ...

随机推荐

  1. 算法基础_递归_给定m个A,n个B,一共有多少种排列

    问题描述: 给定m个A,n个B,一共有多少种排列 解题源代码: /** * 给定m个A,n个B,问一共有多少种排列 * @author Administrator * */ public class ...

  2. 01day

    01 cpu 内存 硬盘 操作系统  CPU:中央处理器,相当于人大脑.   (运行速度飞机)   内存:临时存储数据. 8g,16g,          (高铁)   1,成本高.   2,断电即消 ...

  3. [daily][fedora][netctl][nmcli] 设置笔记本为台式机网关

    TAG:将一个网卡动态增减到网桥里的配置 场景是这样的. 我的笔记本无线网卡用来访问互联网.OS里面有一个birdge用来链接所有的虚拟机帮助虚拟机上网. 现在有了一台台式机.台式机用来做hyperv ...

  4. 洛谷P2743 乐曲主题Musical Themes [USACO5.1] SA

    正解:SA 解题报告: 传送门 这题三个条件嘛,那就一个个考虑下都解决了就把这题解决了嘛QwQ 那就直接分别针对三个条件写下各个击破就欧克辣? 1)长度大于等于5:求出答案之后和5比大小 2)不能有公 ...

  5. linux下查看php-fpm是否开启以及如何开启

    对于linux接触很少,对于命令很不熟,今天发现之前部署的站点无法访问了,就想可能是nginx或者php-fpm没有开启. 所以这里记录linux下查看php-fpm是否开启以及如何开启(nginx也 ...

  6. eclipse 安装 lombok插件

    下载插件 官网下载 :https://projectlombok.org/ 有些小伙伴官网可能打不开,现提供我的下载地址:https://files.cnblogs.com/files/niceyoo ...

  7. android studio中编译单个文件

    网上搜到比较全的是这个:https://blog.csdn.net/u011368551/article/details/51980678 另外关于gradle如何编译单个文件,参考 https:// ...

  8. MFC 的资源文件 就是那个后缀名是 .rc的那个

    参考: http://blog.csdn.net/zgrjkflmkyc/article/details/16897881 http://www.oschina.net/question/565065 ...

  9. JavaScript中的BOM和DOM

    javascript组成: 1. ECMAScript 基本语法. 2. BOM (浏览器对象模型) 3. DOM (文档对象模型) 简单的说就是 BOM是浏览器对象模型,用来获取或设置浏览器的属性. ...

  10. css3动态计算元素的高度及宽度

    1.px     像素,我们在网页布局中一般都是用px. 2.百分比     百分比一般宽泛的讲是相对于父元素,自适应网页布局越来越多,百分比也经常用到了 3.Viewport 当已知一个div的高度 ...