在发生异常时关闭由 flatMap 打开的 Java 8 流?

Eti*_*ret 2 java exception java-stream

Javadoc 指出Stream.flatMap (Function <T, Stream<U>> mapper)

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

好的。但是异常处理呢?

考虑以下:

public List<Path> search (List<Path> paths) {
  return paths.stream ()
    .flatMap (dir -> {
      try {
        return Files.list (dir);
      } catch (IOException e) {
        throw new UncheckedIOException (e);
      }
    })
    .filter (this::mightThrowException)
    .collect (toList ());
}
Run Code Online (Sandbox Code Playgroud)

如果Files.list (Path)在第一次调用时抛出异常,则它的流永远不会首先打开,因此不需要关闭。如果它在以后的调用中抛出异常,则先前调用生成的流都已按照.flapMap ()其规范完全处理并关闭。

但是如果过滤器抛出异常会发生什么?我们正在处理文件列表流,所以我想我需要在某处关闭某些内容,但我不知道到底是什么。最初的paths.stream ()也许?然后哪个会调用派生流上的 close 方法?

注意:对于任何不熟悉Files.list (Path)静态方法的人来说,它返回一个Stream<Path>需要关闭的值(与大多数流不同)。

Ale*_*lex 6

源代码显示,Stream返回的内容flatMap立即包装在带有资源的 try 中,因此即使下游操作抛出异常,它也会被关闭。

更新 javadocflatMap以明确声明这将会发生可能是个好主意。