Mal bufferInput上的IO bufferReader vs nio Files.newBufferedReader CharsetDecoder leniency

时间:2017-02-04 20:13:43

标签: java io bufferedreader nio

我有一个包含无效“UTF-8”字符的文本文件,导致我的应用程序抛出MalformedInputException。我使用Files.newBufferedReader创建BufferReader

Path path = FileSystems.getDefault().getPath(inputDirectory, fileName);
BufferedReader br = Files.newBufferedReader(path, Charset.defaultCharset());

这似乎对字符编码很严格。我做了一些挖掘并在网上发现我们可以通过CharactorDecoder覆盖.onMalformedInput(CodingErrorAction.REPLACE)默认操作来提高宽大度。这似乎解决了这个问题。

然后出于好奇,我使用java IO BufferedReader来读取同一个文件。

fr = new FileReader(file);
br = new BufferedReader(fr);

这似乎对无效字符没有任何问题,并且没有任何问题地阅读该文件。

所以我查看了Files.newBufferedReadernew BufferedReader(fr)的代码。这就是他们实现的方式

Files.newBufferedReader

public static BufferedReader newBufferedReader(Path path, Charset cs)
    throws IOException
{
    //onMalformedInput is not overridden. Thus strict decoding
    CharsetDecoder decoder = cs.newDecoder();

    //Look at how the InputStreadReader created. The decoder being passed
    Reader reader = new InputStreamReader(newInputStream(path), decoder);

    return new BufferedReader(reader);
}

IO BuffereReader

//Creating File Reader
 FileReader fr = new FileReader(file);

 --------------------------------------------------------------------
//File Reader constructor
public FileReader(File file) throws FileNotFoundException {
    //Calls it's supper constructor InputStreamReader
    super(new FileInputStream(file));
}

-----------------------------------------------------------
//InputStreamReader Constructor
public InputStreamReader(InputStream in) {
    super(in);
    try {
        //This where I don't understand
        sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
    } catch (UnsupportedEncodingException e) {
        throw new Error(e);
    }
}

正如您所看到的,他们都使用StreamDecoder.forInputStreamReader。我知道为什么Files.newBufferedReader有严格的解码器。但我试图了解IO BufferredReader中的哪个位置,它被定义为进行宽松解码。

如果有人能帮助我理解这一点,我真的很感激。

1 个答案:

答案 0 :(得分:0)

宽松解码实际上应由FileReader完成。我找不到指定此内容的文档的任何部分,但是在其代码中也使用onMalformedInput(CodingErrorAction.REPLACE)。我不确定它是否可以在所有JDK实现中以相同的方式被信任。