关闭Reader后是否需要关闭InputStream?

Che*_*eng 46 java

我想知道,关闭读卡器后,是否需要关闭InputStream?

    try {
        inputStream = new java.io.FileInputStream(file);
        reader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
    }
    catch (Exception exp) {
        log.error(null, exp);
    }
    finally {
        if (false == close(reader)) {
            return null;
        }
        // Do I need to close inputStream as well?
        if (false == close(inputStream)) {
            return null;
        }
    }
Run Code Online (Sandbox Code Playgroud)

Jac*_*ack 42

不,你不必.

由于用于Java中的流的装饰器方法可以通过将它们附加到其他流来构建新的流或读取器,因此将通过InputStreamReader实现自动处理.

如果你看看它的来源,InputStreamReader.java你会看到:

private final StreamDecoder sd;

public InputStreamReader(InputStream in) {
  ...
  sd = StreamDecoder.forInputStreamReader(in, this, (String)null);
  ...
}

public void close() throws IOException {
  sd.close();
}
Run Code Online (Sandbox Code Playgroud)

因此,关闭操作实际上会关闭InputStream流读取器的底层.

编辑:我想确保StreamDecoder关闭也适用于输入流,敬请期待.

检查一下,进去 StreamDecoder.java

void implClose() throws IOException {
  if (ch != null)
    ch.close();
  else
    in.close();
}
Run Code Online (Sandbox Code Playgroud)

调用sd的关闭时调用.

  • 您是否发现它明确写在文档中?我不确定它是否是所有Java实现的约束.@Yan Cheng CHEOK:如果在关闭阅读器后关闭输入流,则没有任何危害. (2认同)
  • @Viven Barousse:“关闭流并释放与之关联的所有系统资源。” -- `java.io.Reader` 用于 `close()` 的 JavaDoc (2认同)

Tom*_*ine 8

从技术上讲,收盘Reader将关闭InputStream.但是,如果在打开InputStream和创建之间出现故障Reader,您仍应关闭InputStream.如果你关闭InputStream[资源],应该没有充分的理由关闭Reader[装饰器].还有一些流行的错误,关闭装饰器可以在关闭装饰之前抛出异常.所以:

Resource resource = acquire();
try {
    Decorator decorated = decorate(resource);
    use(decorated);
} finally {
    resource.release();
}
Run Code Online (Sandbox Code Playgroud)

有一些并发症需要注意.由于实现,一些装饰器实际上可能包含本机资源.输出装饰器通常需要刷新,但仅在快乐的情况下(所以在tryfinally块中).

  • 如果`Decorator`例如是`BufferedWriter`,则会失败.它没有明确记录,程序员应该在使用后显式调用`flush()`. (2认同)

amo*_*fis 5

如果您close()是读者,则无需关闭流.

关闭流并释放与其关联的所有系统资源.关闭流后,进一步的read(),ready(),mark(),reset()或skip()调用将抛出IOException.关闭先前关闭的流无效.