关闭Stream会关闭BufferedReader源吗?

nha*_*man 8 java stream

来自文档:

Streams有一个BaseStream.close()方法并实现AutoCloseable,但几乎所有的流实例实际上都不需要在使用后关闭.通常,只有源为IO通道的流(例如Files.lines(Path,Charset)返回的流)才需要关闭.大多数流都由集合,数组或生成函数支持,不需要特殊的资源管理.(如果流确实需要关闭,则可以在try-with-resources语句中将其声明为资源.)

当我创建一个Stream<String>使用lines()方法时BufferedReader,如下所示,关闭Stream也关闭了BufferedReader吗?

try (Stream<String> lines = new BufferedReader(new InputStreamReader(process.getInputStream())).lines()) {
  // Do stuff
}

// Is the BufferedReader, InputStreamReader and InputStream closed?
Run Code Online (Sandbox Code Playgroud)

我试过的一些非常快速的测试说没有(in字段BufferedReader不是null),但后来我对下面的句子感到困惑,因为这个例子也是I/O,对吧?

通常,只有源为IO通道的流(例如Files.lines(Path,Charset)返回的流)才需要关闭.

如果没有,我是否需要关闭这两个实例,或者是否BufferedReader足够关闭?


理想情况下,我想Stream<String>从某种方法返回一个,而不会让客户担心读者.目前,我已经创建了一个Stream装饰器,它也关闭了阅读器,但如果没有必要,它会更容易.

Mat*_*ias 5

如果您希望将阅读器的关闭推迟到交付的Stream,则需要调用Stream.onClose():

static Stream<String> toStream(BufferedReader br){
    return br.lines().onClose(asUncheckedAutoCloseable(br));
}


static Runnable asUncheckedAutoCloseable(AutoCloseable ac) {
    return () -> {
        try {
            ac.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    };
}
Run Code Online (Sandbox Code Playgroud)


Jir*_*riS 3

不,似乎没有。当流是使用创建的

    return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
            iter, Spliterator.ORDERED | Spliterator.NONNULL), false);
Run Code Online (Sandbox Code Playgroud)

它不会传递任何对 the 的引用BufferedReader