来自the docs:
Streams有一个BaseStream.close()方法并实现AutoCloseable, 但几乎所有流实例实际上都不需要关闭 使用后。通常,只有源为IO通道的流(例如 由于Files.lines(Path,Charset)返回的那些将需要关闭。 大多数流都由集合,数组或生成支持 功能,不需要特殊的资源管理。 (如果是一个流 确实需要关闭,它可以被声明为一个资源 尝试使用资源声明。)
当我在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?
我尝试过的一些非常快速的测试说不(in
的{{1}}字段不是BufferedReader
),但后来我对以下句子感到困惑,因为这个例如I / O,对吧?
通常,只有源为IO通道的流(例如 因为Files.lines(Path,Charset)返回的那些将需要关闭。
如果没有,我是否需要关闭两个实例,或者关闭null
是否足够?
理想情况下,我想从某种方法返回BufferedReader
,而不会让客户担心读者。目前,我已经创建了一个Stream<String>
装饰器,它也关闭了阅读器,但如果没有必要,它会更容易。
答案 0 :(得分:5)
如果您想将阅读器的关闭推迟到交付的流,您需要调用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);
}
};
}
答案 1 :(得分:2)
不,似乎没有。使用
创建流 return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
iter, Spliterator.ORDERED | Spliterator.NONNULL), false);
没有传递对BufferedReader
答案 2 :(得分:2)
在您的问题中,您没有展示如何创建Reader
作为new BufferedReader(in)
的参数。但是根据我自己的测试,没有理由假设Stream
关闭了这个论点。
执行以下操作应该关闭所有人:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.stream.Stream;
public class SOPlayground {
public static void main(String[] args) throws Exception {
try (Reader in = new InputStreamReader(new FileInputStream(new File("/tmp/foo.html")));
BufferedReader reader = new BufferedReader(in);
Stream<String> lines = reader.lines()) {
lines.forEach(System.out::println);
}
}
}