提问人:Paper_Folding 提问时间:8/19/2021 最后编辑:Paper_Folding 更新时间:8/19/2021 访问量:395
Java Nio ByteBuffer 在缓冲区达到其边界时截断 Unicode 字符
Java Nio ByteBuffer truncate unicode characters when buffer reaches its bound
问:
我正在用 java 编写一个函数,该函数可以读取文件并将其内容转换为 String:
public static String ReadFromFile(String fileLocation) {
StringBuilder result = new StringBuilder();
RandomAccessFile randomAccessFile = null;
FileChannel fileChannel = null;
try {
randomAccessFile = new RandomAccessFile(fileLocation, "r");
fileChannel = randomAccessFile.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
CharBuffer charBuffer = null;
int bytesRead = fileChannel.read(byteBuffer);
while (bytesRead != -1) {
byteBuffer.flip();
charBuffer = StandardCharsets.UTF_8.decode(byteBuffer);
result.append(charBuffer.toString());
byteBuffer.clear();
bytesRead = fileChannel.read(byteBuffer);
}
} catch (IOException ignored) {
} finally {
try {
if (fileChannel != null)
fileChannel.close();
if (randomAccessFile != null)
randomAccessFile.close();
} catch (IOException ignored) {
}
}
return result.toString();
}
从上面的代码中,您可以看到我故意将“ByteBuffer.allocate”设置为仅 10 个字节,以使事情更清晰。 现在我想读取一个名为“test.txt”的文件,其中包含中文的 unicode 字符,如下所示:
乐正绫我爱你乐正绫我爱你
以下是我的测试代码:
System.out.println(ReadFromFile("test.txt"));
控制台中的预期输出
乐正绫我爱你乐正绫我爱你
控制台中的实际输出
乐正绫���爱你��正绫我爱你
可能的原因
ByteBuffer 只分配了 10 个字节,因此 unicode 字符每 10 个字节被截断一次。
尝试解决
将 ByteBuffer 分配的字节增加到 20,我得到了以下结果:
乐正绫我爱你��正绫我爱你
不是一个强大的解决方案
将 ByteBuffer 分配给一个非常大的数字,比如 102400,但当涉及到非常大的文本文件时,这是不切实际的。
问:
如何解决这个问题?
答:
2赞
Kayaman
8/19/2021
#1
你不能,因为你不知道 UTF-8 编码中每个字符使用了多少个字节,而且你真的不想重写这个逻辑。
Java 11 中有 Files.readString(),对于较低版本,您可以使用 Files.readAllBytes(),例如
Path path = new File(fileLocation).toPath()
String contents = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
评论
0赞
Joachim Sauer
8/19/2021
我试图弄清楚如何在这里正确使用 CharsetDecoder.decodeLoop
,直到我意识到 OP 只是编写了一种非常复杂的方法来读取整个文件内容作为......String
0赞
Paper_Folding
8/19/2021
嘿,我想知道是否有任何类似的方法可以编写 String 来如此轻松地提交文件,因为我也编写了一个非常复杂的 WriteStringToFile 方法。
0赞
user207421
8/19/2021
@Paper_Folding .java.net.FileWriter
0赞
Paper_Folding
8/19/2021
@user207421 解决方式java.nio.file.Files.writeString
下一个:异步/同步操作的确切工作原理
评论
FileReader
read