【问题标题】:Why does RandomAccessFile read  as firt character in my UTF-8 text file?为什么 RandomAccessFile 读取  作为我的 UTF-8 文本文件中的第一个字符?
【发布时间】:2018-08-30 13:53:00
【问题描述】:

关于在 Java 中读取文本文件的问题。我有一个使用 UTF-8 编码保存的文本文件,其中只有内容:

你好。世界。

现在我使用RandomAccessFile 来阅读这门课。但是由于某种原因,文件开头似乎有一个“隐形”字符...?

我使用这个代码:

File file = new File("resources/texts/books/testfile2.txt");
try(RandomAccessFile reader = new RandomAccessFile(file, "r")) {

    String readLine = reader.readLine();
    String utf8Line = new String(readLine.getBytes("ISO-8859-1"), "UTF-8" );
    System.out.println("Read Line: " + readLine);
    System.out.println("Real length: " + readLine.length());
    System.out.println("UTF-8 Line: " + utf8Line);
    System.out.println("UTF-8 length: " + utf8Line.length());
    System.out.println("Current position: " + reader.getFilePointer());
} catch (Exception e) {
    e.printStackTrace();
}

输出是这样的:

Read Line: ?»?Hello. World.
Real length: 16
UTF-8 Line: ?Hello. World.
UTF-8 length: 14
Current position: 16

这些(1 或 2)个字符似乎只出现在开头。如果我在文件中添加更多行并读取它们,那么所有其他行都将被正常读取。 有人可以解释这种行为吗?开头这个字符是什么?

谢谢!

【问题讨论】:

  • 可能是 BOM。

标签: java utf-8 randomaccessfile


【解决方案1】:

文件中的前 3 个字节(0xef0xbb0xbf)称为 UTF-8 BOM(字节顺序标记)。 BOM 仅对 UTF-16 和 UTF-32 很重要 - 对于 UTF-8 没有意义。微软引入它是为了更好地猜测文件编码。

也就是说,并非所有 UTF-8 编码的文本文件都有该标记,但有些有。

【讨论】:

  • "对于 UTF-8 它没有意义" - 这不是真的。它与 UTF-16 BOM 或 UTF-32 BOM 具有相同的含义 - 指定文件编码。只是它仅适用于 BOM 感知应用程序。为了与旧版应用程序向后兼容,对于要与不知道如何处理 BOM 的旧版应用程序一起使用的文件,不建议将 BOM 放入 UTF-8 文本文件中。跨度>
  • @RemyLebeau,你错了,对不起。 BOM - 顾名思义 - 是关于字/双字(“字节序”)中的字节顺序。它对所用编解码器的来宾的利用与它的初衷无关,并且提供的只是一个来宾。它是 2 字节序列 0xfeff - Unicode 零宽度无间断空格符号 U+FEFF。相比之下,3字节序列0xefbbbf与字节顺序无关(因为在UTF-8中字节顺序是明确的),所以它的名字BOM很傻。
  • Per unicode.org: "一个字节顺序标记 (BOM) ... 可以用作签名 定义字节顺序和编码形式... 无论 Unicode 文本如何转换,BOM 都可以用作签名:UTF-16、UTF-8 或 UTF-32...BOM 用于表明它是一个 Unicode 文件,以及 它采用哪种格式... UTF-8 可以包含 BOM... UTF-8 始终具有相同的字节顺序。初始 BOM 仅用作签名 - 表示其他未标记的文本文件采用 UTF-8 格式。"
  • @RemyLebeau,谢谢,您的引用支持我写的内容。
  • 我的意思是,尽管它的名字,BOM更多不仅仅是用于指示字节顺序。 ALSO 用作编码指示符,适用于 UTF-8(和其他单字节 UTF,例如 UTF-7),而不仅仅是 UTF-16/32。 Unicode 联盟确认并记录它。
猜你喜欢
  • 2013-06-28
  • 1970-01-01
  • 2013-11-25
  • 2011-10-23
  • 2016-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-24
相关资源
最近更新 更多