流上的收集操作是否会关闭流和基础资源?

下面的代码是否需要包装在 try-with-resources 中以确保基础文件已关闭?

List<String> rows = Files.lines(inputFilePath).collect(Collectors.toList());

答案 1

有一个技巧可以在终端操作之后调用实现:Streamclose()

List<String> rows = Stream.of(Files.lines(inputFilePath)).flatMap(s->s)
                   .collect(Collectors.toList());

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

有趣的一点是Stream.flatMap(...)一个属性:

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

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


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

List<String> rows = Files.readAllLines(inputFilePath);

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


答案 2

正如重载 Files#lines(Path, Charset) 方法的 javadoc 所声明的那样

返回的流封装了 .如果需要及时处置文件系统资源,则应使用构造来确保在流操作完成后调用流的 close 方法。Readertry-with-resources

所以,是的,将返回的 by 包装在语句中。(或适当地关闭它。Streamlinestry-with-resources