java读取UTF-8的txt文件发现开头的一个字符问题
今天遇到一个奇葩问题,在读取一个TXT文件时,出现开头多了一个问号(?)。如下图:

莫名奇妙的多了一个。最后通过网上资料,知道在Java中,class文件采用utf8的编码方式,JVM运行时采用utf16。Java的字符串是永远都是unicode的,采用的是UTF-16的编码方式。
想测试一下,java对UTF-8文件的读写的能力,结果发现了一个很郁闷的问题,如果通过java写的UTF-8文件,使用Java可以正确的读,但是如果用记事本将相同的内容使用UTF-8格式保存,则在使用程序读取是会从文件中多读出一个不可见字符。
测试代码如下:
- 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 second line.
正常的测试结果应该是直接输出utf.txt的文本内容。可是实际上却输出了下面的内容:
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文件发现开头的一个字符问题的更多相关文章
- java将数据写入到txt文件中(txt有固定的格式)
java将数据写入到txt文件中,这个应该对于学过java I/O的人来说是很简单的事情了,但是如果要将数据以固定的格式写入到txt文件中,就需要一定的技巧了. 这里举个简单的例子,以供参考: 比如我 ...
- C# 读取大文件 (可以读取3GB大小的txt文件)
原文:C# 读取大文件 (可以读取3GB大小的txt文件) 在处理大数据时,有可能 会碰到 超过3GB大小的文件,如果通过 记事本 或 NotePad++去打开它,会报错,读不到任何文件. 如果你只是 ...
- 关于Java里面File类创建txt文件重复???
private JButton getOpenButton() { if (openButton == null) { openButton = new JButton(); openButton.s ...
- java读取resource/通过文件名获取文件类型
java读取resource java读取resource目录下文件的方法: 借助Guava库的Resource类 Resources.getResource("test.txt" ...
- 【转】Java读取matlab的.mat数据文件
参考:Java读取mat文件 下载链接:ujmp jmatio 下载完两个.jar文件之后,如何引用到java项目当中?项目名称->右键->Property->Java Build ...
- Java导出List集合到txt文件中——(四)
有时候,需要将数据以一定格式导出到txt文件中.利用Java的IO可以轻松的导出数据到txt中. package Action.txt; import java.io.BufferedWriter; ...
- 解决:java 读取 resources 下面的 json 文件
前言:java 读取 工程下的配置文件,文件类型为 json(*.json),记录一下始终读取不到 json 文件的坑.maven项目 直接上工具类代码 package com.yule.compon ...
- java存储数据到本地txt文件中
java存储数据,方便打印日志等 1.会覆盖以前的数据 try { File writeName = new File("D:\\data.txt"); // 相对路径,如果没有则 ...
- java读取jar包中的文件
随手写了一个java小工具,maven打包成功后,发现工具总是读不到打在jar包中的文件信息,要读取的文件位于 /src/main/resources 目录下,打包成功后,文件就在jar包中根目录下, ...
随机推荐
- pytorch入门与实践-2.2
Tensor 1--本质上可以理解为具有不同维度的数组 2--支持的基本运算 |---创建Tensor: x=t.tensor(x,y) x,y 表示数组的大小 , x=t.rand(x,y), x ...
- Codeforces 1062 - A/B/C/D/E - (Undone)
链接:http://codeforces.com/contest/1062 A - Prank - [二分] 题意: 给出长度为 $n(1 \le n \le 100)$ 的数组 $a[1 \sim ...
- 【转载】word2vec原理推导与代码分析
本文的理论部分大量参考<word2vec中的数学原理详解>,按照我这种初学者方便理解的顺序重新编排.重新叙述.题图来自siegfang的博客.我提出的Java方案基于kojisekig,我 ...
- Oracle 数据库逻辑结构.md
一.存储关系Oracle 数据库逻辑上是由一个或多个表空间组成的,表空间物理上是由一个或多个数据文件组成的:而在逻辑上表空间又是由一个或多个段组成的.在Oracle 数据库中,通过为每种不同的数据对象 ...
- 算数运算符: + - * / //(地板除) %(取余) **(幂运算) / 比较运算符 > < >= <= == !=
# ### python运算符 #(1) 算数运算符: + - * / //(地板除) %(取余) **(幂运算) var1 = 5 var2 = 8 # +res = var1 + var2 pri ...
- keras框架 反复调用model 模型 出错
Cannot interpret feed_dict key as Tensor: Tensor Tensor("Placeholder_8:0", shape=(3, 3, 12 ...
- 使用 Asp.net core 2.0 + Angular 4 构建车辆管理的Web应用程序
https://www.codeproject.com/Articles/1210559/Asp-net-core-Angular-Build-from-scratch-a-web
- vue中使用scss
之前项目里我一般是使用less的,朋友问到如何引入scss,于是我就简单的跑了一下,以下主要供自己学习,如有更好的方法可以一起交流讨论一下 第一步,安装依赖 cnpm install node-sas ...
- git----------SourceTree如何连接ssh的仓库地址,这里记录的是客户端需要做的事
1. 2. 打开命令行以后输入ssh-keygen -t rsa -C "example@example.com" 这个地方输入的是你注册gitlab所使用的邮箱.按回车,之后还 ...
- Django之天天生鲜项目
准备工作 1.配置settings.py内置文件 注意: AUTH_USER_MODEL配置参数要在第一次迁移数据库之前配置,否则可能django的认证系统工作不正常 2.创建应用 3.配置主路由 一 ...