每个函数

时间:2016-11-16 10:23:25

标签: java java-8 java-stream

当我们使用Stream.concat连接流时,是否可以在流结束时运行函数?

e.g。

我正在使用Files.lines从多个文件创建流。现在,只要文件被完全读取,我就需要将其删除。

2 个答案:

答案 0 :(得分:3)

当结果流关闭时,将执行通过Stream.concat组成的流的关闭处理程序。请注意,关闭处理程序通常要求使用流的代码关闭流,例如

try(Stream<String> s=Stream.concat(Files.lines(path1), Files.lines(path2))) {
    s.forEach(System.out::println);
}

正确关闭和

try(Stream<String> s=Stream.concat(
        Files.lines(path1).onClose(()->{
            try { Files.delete(path1); }
            catch (IOException ex) { throw new UncheckedIOException(ex); }
        }),
        Files.lines(path2).onClose(()->{
            try { Files.delete(path2); }
            catch (IOException ex) { throw new UncheckedIOException(ex); }
        }))
    ) {

    s.forEach(System.out::println);
}

之后删除文件。但在这种情况下,生成的流的关闭处理程序将调用源流的关闭处理程序,因此这不会在使用后立即删除文件,但在整个操作之后,因此它与

没有太大区别
try(Closeable c1=() -> Files.deleteIfExists(path1);
    Closeable c2=() -> Files.deleteIfExists(path2);
    Stream<String> s=Stream.concat(Files.lines(path1), Files.lines(path2)); ) {

    s.forEach(System.out::println);
}

如果您想及时删除文件,则必须使用flatMap。无论“外部”流是否将关闭,子流将在使用后立即关闭:

Stream.of(path1, path2)
      .flatMap(path -> {
            try { return Files.lines(path).onClose(()->{
                try { Files.delete(path); }
                catch (IOException ex) { throw new UncheckedIOException(ex); }
            }); }
            catch (IOException ex) { throw new UncheckedIOException(ex); }
        })
       .forEach(System.out::println);

为了证明这种差异,

try(Stream<String> s=Stream.concat(
        Stream.of("foo").onClose(()->System.out.println("foo closed")),
        Stream.of("bar").onClose(()->System.out.println("bar closed")) )) {
    s.forEach(System.out::println);
}

将打印

foo
bar
foo closed
bar closed

,而

Stream.of("foo", "bar")
    .flatMap(x -> Stream.of(x).onClose(()->System.out.println(x+" closed")) )
    .forEach(System.out::println);

将打印

foo
foo closed
bar
bar closed

答案 1 :(得分:0)

您是否尝试过使用Stream.onClose()。像Stream.concat()。onClose()