java - 使用 Files.newBufferedReader() 读取文件和直接构造读取器的不同结果

标签 java file utf-8 java-8 nio2

似乎 Files.newBufferedReader() 对 UTF-8 的要求比单纯的替代方案更严格。

如果我创建一个只有一个字节 128 的文件——所以,不是一个有效的 UTF-8 字符——如果我在 上构造一个 BufferedReader,它会被愉快地读取InputStreamReaderFiles.newInputStream() 的结果上,但对于 Files.newBufferedReader() 会引发异常。

这段代码

try (
    InputStream in = Files.newInputStream(path);
    Reader isReader = new InputStreamReader(in, "UTF-8");
    Reader reader = new BufferedReader(isReader);
) {
    System.out.println((char) reader.read());
}

try (
    Reader reader = Files.newBufferedReader(path);
) {
    System.out.println((char) reader.read());
}

有这样的结果:

�
Exception in thread "main" java.nio.charset.MalformedInputException: Input length = 1
    at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.read(BufferedReader.java:182)
    at TestUtf8.main(TestUtf8.java:28)

这有记录吗?是否有可能通过 Files.newBufferedReader() 获得宽松的行为?

最佳答案

区别在于在这两种情况下如何构造用于解码 UTF-8 的 CharsetDecoder

对于 new InputStreamReader(in, "UTF-8") 解码器是使用以下方法构建的:

Charset cs = Charset.forName("UTF-8");

CharsetDecoder decoder = cs.newDecoder()
          .onMalformedInput(CodingErrorAction.REPLACE)
          .onUnmappableCharacter(CodingErrorAction.REPLACE);

这明确指定无效序列仅被替换为标准替换字符。

Files.newBufferedReader(path) 使用:

Charset cs = StandardCharsets.UTF_8;

CharsetDecoder decoder = cs.newDecoder();

在这种情况下,onMalformedInputonUnmappableCharacter 未被调用,因此您将获得默认操作,即抛出您所看到的异常。

似乎没有办法改变 Files.newBufferedReader 的功能。在查看代码时,我没有看到任何对此进行记录的内容。

关于java - 使用 Files.newBufferedReader() 读取文件和直接构造读取器的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34886312/

相关文章:

java - 获取 XML 文件中所有属性的名称

c++ - 使用包含字符和数字的 C++ 读取文件

python - 如何修复 "OverflowError: Unsupported UTF-8 sequence length when encoding string"

Scala - 从 ISO-8859-1 转换为 UTF-8 会产生陌生字符

java - 使用 ByteArrayOutputStream 进行 UTF-8 编码

java - Cassandra 每日数据清除?

java - java中的十进制输入edittext

java - 如何使用 Regex 允许尖括号 <> 之间没有任何字符?

file - 如何在 R 中创建数据加载进度条?

angular - 从 ngx-image-cropper 返回文件以上传 - Angular