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()); 

它只是创建一个将行流封装为单个项的流,并使用带有标识函数的flatMapFunction.identity()也可以))将其再次转换为行流。

有趣的是Stream.flatMap(…)的属性 :

每个映射的流在其内容放入此流后关闭。

所以上面的代码将关闭行流。 虽然它看起来更简洁,但它比使用资源尝试更有缺点,因为flatMap当前实现缺乏惰性评估 ,这在此flatMap ,因为您无论如何都要将所有行收集到列表中。 但是在其他场景中使用这个技巧时要记住这一点。


对于问题的代码,有一个更简单的解决方案:

 List rows = Files.readAllLines(inputFilePath); 

读取所有行并关闭所有资源……