关闭在异常情况下由flatMap打开的Java 8流?

huangapple go评论77阅读模式
英文:

Closing a Java 8 stream opened by flatMap in case of exception?

问题

Stream.flatMap(Function<T, Stream<U>> mapper)的Javadoc说明如下:

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

不错。但异常处理呢?

考虑以下代码:

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

如果Files.list(Path)在第一次调用时抛出异常,其流根本就没有被打开,因此不需要关闭。如果它在以后的调用中抛出异常,根据.flatMap()的规范,从先前调用生成的流已经全部被完全处理和关闭。

但如果筛选器抛出异常会怎么样?我们正在处理文件列表流的中途,所以我猜我需要在某个地方关闭一些东西,但我不明白具体是什么。最初的paths.stream()可能吗?然后会调用派生流上的关闭方法?

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

英文:

The Javadoc from Stream.flatMap (Function &lt;T, Stream&lt;U&gt;&gt; mapper) states:

> Each mapped stream is closed after its contents have been placed into this stream.

Nice. But what about exception handling?

Consider the following:

public List&lt;Path&gt; search (List&lt;Path&gt; paths) {
  return paths.stream ()
    .flatMap (dir -&gt; {
      try {
        return Files.list (dir);
      } catch (IOException e) {
        throw new UncheckedIOException (e);
      }
    })
    .filter (this::mightThrowException)
    .collect (toList ());
}

If Files.list (Path) throws an exception on the first call, its stream is never opened in the first place, so doesn't need closing. If it throws an exception on a later call, the streams generated from previous calls have all been fully processed and closed by .flapMap () per its specification.

But what happen if the filter throws an exception? We're in the middle of processing a file listing stream, so I guess I need to close something somewhere, but I don't get what exactly. The initial paths.stream () maybe? which would then call the close method on derived streams?

NB: for anyone not familiar with the Files.list (Path) static method, it returns a Stream&lt;Path&gt; that (unlike most streams) needs to be closed.

答案1

得分: 5

这个 源代码 显示,返回给 flatMapStream 会立即被放在一个 try with resources 中进行包装,因此即使下游操作抛出异常,它也会被关闭。

最好更新 flatMap 的 javadoc 来明确说明这一点。

英文:

The source shows that the Stream returned to flatMap is immediately wrapped in a try with resources, so it will be closed even if a downstream operation throws an exception.

It might be a good idea to update the flatMap javadoc to explicitly state that this will happen.

huangapple
  • 本文由 发表于 2020年9月29日 19:35:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/64118801.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定