Stream上的收集操作是否会关闭流和底层资源?

时间:2015-07-01 20:54:24

标签: java file-io java-8 java-stream try-with-resources

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

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

2 个答案:

答案 0 :(得分:18)

终端操作后,有一个技巧可以使Stream实现调用close()

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

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

有趣的是property of Stream.flatMap(…)

  

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

因此上面的代码将关闭行流。虽然它看起来更简洁,但它比使用资源尝试flatMap lacks lazy evaluation的优势更加不利于此,因为您无论如何都要将所有行收集到列表中。但是在其他场景中使用这个技巧时要记住这一点。

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

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

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

答案 1 :(得分:11)

由于重载的Files#lines(Path, Charset)方法的javadoc声明了

  

返回的流封装了Reader。如果及时处理档案   系统资源是必需的,try-with-resources构造应该   用于确保在之后调用流的close方法   流操作完成。

所以是的,将Stream返回的lines包装在try-with-resources语句中。 (或close恰当。)