Stream上的收集操作是否关闭流和底层资源?
以下代码是否需要包含在try-with-resources中以确保底层文件已关闭?
List rows = Files.lines(inputFilePath).collect(Collectors.toList());
由于重载的Files#lines(Path, Charset)
方法的javadoc状态
返回的流封装了一个
Reader
。 如果需要及时处理文件系统资源,则应使用try-with-resources
构造来确保在流操作完成后调用流的close方法。
所以是的,在try-with-resources
语句中包装由lines
返回的Stream
。 (或者适当地关闭它。)
有一个技巧可以使Stream
实现在终端操作后调用close()
:
List rows = Stream.of(Files.lines(inputFilePath)).flatMap(s->s) .collect(Collectors.toList());
它只是创建一个将行流封装为单个项的流,并使用带有标识函数的flatMap
( Function.identity()
也可以))将其再次转换为行流。
有趣的是Stream.flatMap(…)
的属性 :
每个映射的流在其内容放入此流后关闭。
所以上面的代码将关闭行流。 虽然它看起来更简洁,但它比使用资源尝试更有缺点,因为flatMap
当前实现缺乏惰性评估 ,这在此flatMap
,因为您无论如何都要将所有行收集到列表中。 但是在其他场景中使用这个技巧时要记住这一点。
对于问题的代码,有一个更简单的解决方案:
List rows = Files.readAllLines(inputFilePath);
读取所有行并关闭所有资源……