如何从中间操作关闭流中的资源(Java 8)
我从几篇文章和文档中读到,流中的资源不会自动关闭 但我想知道是否有一种很好的方法可以关闭来自中间操作的流中的资源。类似下面的代码:如何从中间操作关闭流中的资源(Java 8),java,java-8,java-stream,Java,Java 8,Java Stream,我从几篇文章和文档中读到,流中的资源不会自动关闭 但我想知道是否有一种很好的方法可以关闭来自中间操作的流中的资源。类似下面的代码: public class MyTest { @Test public void main() throws Exception { test().forEach(System.out::println); } public List<String> test() throws Exception {
public class MyTest {
@Test
public void main() throws Exception {
test().forEach(System.out::println);
}
public List<String> test() throws Exception {
Path myPath = Paths.get(this.getClass().getClassLoader().getResource("test").toURI());
Function<Path, Stream<String>> mapper = path -> {
try {
return Files.lines(path, StandardCharsets.UTF_8);
} catch (IOException e) {
throw new UncheckedIOException("File cannot be read: " + path, e);
}
};
try {
return Files.list(myPath).peek(System.out::println)
.flatMap(mapper).peek(System.out::println)
.map(s -> s + " mapped").peek(System.out::println)
.collect(Collectors.toList());
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
公共类MyTest{
@试验
public void main()引发异常{
test().forEach(System.out::println);
}
public List test()引发异常{
Path myPath=Path.get(this.getClass().getClassLoader().getResource(“test”).toURI());
函数映射器=路径->{
试一试{
返回Files.line(路径,StandardCharsets.UTF_8);
}捕获(IOE异常){
抛出新的未选中的异常(“无法读取文件:“+path,e”);
}
};
试一试{
返回Files.list(myPath).peek(System.out::println)
.flatMap(mapper).peek(System.out::println)
.map(s->s+“映射”).peek(System.out::println)
.collect(Collectors.toList());
}捕获(IOE异常){
抛出新的未选中异常(e);
}
}
}
为了避免IllegalStateException(类似于“stream is ready closed”),我想我不能在名为mapper的lambda表达式中使用try with resources,但是什么时候是关闭流的好时机?显然您还没有完全阅读链接的Q&A,即
flatMap
已经负责关闭由mapper
返回的流@Holger Hi,非常感谢。我发现您所说的虽然看起来更简洁,但与使用资源进行尝试相比,它有一个缺点,即如果在两者之间发生异常,当前实现不会关闭流。
在链接的答案中,当我需要确保即使发生异常也关闭所有资源时,是否有任何解决方案?在应用程序端无法修复此类问题。但显然,JRE开发人员已经解决了这个问题。我将检查添加了哪个版本的修复程序,然后我将更新该答案。@Holger,这将非常感谢。所以实际上我们可以使用flatMap而不考虑最新JRE下的资源泄漏,对吗?我已经删除了那个部分。我无法追溯这个问题,即使是在较旧的JRE下,所以最有可能的错误是在我这边。资源应该关闭,因此您可以使用flatMap
,而不用担心资源泄漏。