【问题标题】:Wrong output when attempting to read a text file尝试读取文本文件时输出错误
【发布时间】:2015-06-23 06:04:50
【问题描述】:

我想读取文本文件并将其打印到控制台,所以我使用以下代码进行了此操作

File file = new File("G:\\text.txt");
FileReader fileReader = new FileReader(file);
int ascii = fileReader.read();

while (ascii != -1)
{
result = result + (char) ascii;
ascii = fileReader.read();
}
System.out.println(result);

虽然我得到了正确的结果,但在某些情况下我会得到一些奇怪的结果。假设我的文本文件中包含以下文本:

Hello to every one

为了有一个文本文件,我使用了记事本,当我改变编码模式时,我的代码会得到奇怪的输出。

Ansi : 大家好

Unicode : ÿþh e l l o t o e v e r y o n e

Unicode 大端:þÿ h e l l o t o e v e r y o n e

UTF-8 : 大家好

为什么我会得到这些奇怪的输出?我的代码有问题吗?或者还有其他原因

【问题讨论】:

  • 因为编码方式?您已经提到,当您更改编码模式时会发生这种情况..
  • @Gosu:是的,正如你所看到的,当我改变编码模式时,我得到了不同的结果
  • 改用 InputStreamReader 和正确的编码模式?
  • @ElyasHadizadeh 你认为不同的编码有什么用途?如果它们都给出相同的结果,我们只需要一个编码。您还在最后一个示例(UTF-8)中使用了正确的术语(编码)。 Ansi 不是一种编码,你所说的 unicode 实际上是 UTF-16LE 和 UTF-16BE。 Unicode 是字符集,编码是将字符存储为字节的不同方式。
  • @ElyasHadizadeh 这是一本不错的读物:joelonsoftware.com/articles/Unicode.html

标签: java character-encoding java-io


【解决方案1】:

您的文件以byte-order mark (U+FEFF) 开头。它应该只出现在文件的第一个字符中——它的使用并不广泛,但各种 Windows 工具都包含它,包括记事本。你可以从第一行开始去掉它。

顺便说一句,我强烈建议不要使用FileReader - 它不允许您指定编码。我会使用Files.newBufferedReader,并指定编码或让它默认为UTF-8(而不是FileReader 使用的系统默认编码)。当您使用BufferedReader 时,您也可以使用readLine() 一次读取一行:

 String line;
 while ((line = reader.readLine()) != null) {
     System.out.println(line.replace("\uFEFF", ""));
 }

如果您真的想要一次读取一个字符,那么值得养成使用StringBuilder 的习惯,而不是在循环中重复字符串连接。另请注意,ascii 的变量名具有误导性:它实际上是 UTF-16 代码单元,可能是也可能不是 ASCII 字符。

您指定的编码应该与用于写入文件的编码相匹配 - 此时您应该看到正确的输出,而不是在使用 Unicode 和 Unicode 大端序时每个“真实”字符之间的额外字符。

【讨论】:

  • 看来你的回答是对的,请你写出Files.newBufferedReader的正确使用方法?!
  • @ElyasHadizadeh:您看过文档并尝试自己使用吗?能够进行自己的研究非常重要。
  • 是的,你完全是真的,谢谢你的建议和回答;-)
  • Jon Skeet:再次非常非常感谢,我找到了正确的方法,实际上这行代码:line.replace("\uFEFF", "") 很有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-31
相关资源
最近更新 更多