1
file = new RandomAccessFile(filename, "rw");
channel = file.getChannel();
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
buffer.load();  
for (int i = 0; i < buffer.limit(); i++)
{
       System.out.print((char) buffer.getChar());
}

然而,这会吐出非 UTF8 字符。我知道我在这里遗漏了一些小东西!

4

1 回答 1

2

首先,您的术语在这里有些混乱(我认为)。Java 字符是 UTF-16 而不是 UTF-8。您不会期望char. (事实上​​,UTF-8 使用 1 到 5bytes来编码单个 Unicode 代码点。在许多情况下,字符的 UTF-8 编码不适合char...)

这种术语混乱意味着我无法确定您实际上在尝试做什么,或者您实际看到的是什么。所以我你实际上是在尝试读取一个(你相信)以 UTF-8 编码的文件......或者可能是 7 或 8 位编码,如 ASCII 或 Latin-1。

在这种情况下,主要问题是该getChar()方法没有达到您的预期。

您的代码似乎假设getChar将(以某种方式)负责从缓冲区中的字节解码“下一个字符”。事实上,它所做的是获取缓冲区中接下来的两个字节......无论它们是什么......组合它们(使用按位“移位”和“或”)并将它们作为char. 结果与原始文件中的字符不会有太多相似之处。实际上,您很可能会得到随机的 Unicode 字符序列,偶尔会出现不可打印甚至非法的“东西”。(有些char值是保留的,要么不能使用,要么必须以正确的顺序使用。)

第二个问题是您的循环将尝试“读取”比缓冲区中更多的字符。该limit()方法返回字节数,而不是字符数。

我的建议与 EJP 的建议基本相同。对于文本,使用 aCharBufferCharsetDecoder

于 2013-11-13T11:45:11.853 回答