【问题标题】:Java 8 Streams: streaming files and delete after readJava 8 Streams:流式传输文件并在读取后删除
【发布时间】:2020-05-19 19:07:02
【问题描述】:

我想流式传输文件中包含的行,但在处理完每个文件后将其删除。

目前的流程是这样的:

解释:

  1. 我创建了一个文件流
  2. 我为它们中的每一个创建一个 BufferedReader
  3. 我将平面映射到 BufferedReader 的行流
  4. 我打印每一行。

代码:

(1)    Stream.generate(localFileProvider::getNextFile)
(2)       .map(file -> return new BufferedReader(new InputStreamReader(new FileInputStream(file))))
(3)       .flatMap(BufferedReader::lines)
(4)       .map(System.out::println);

是否可以在完全读取每个文件后将其删除并继续处理流中的其他文件?

谢谢!

【问题讨论】:

  • 流有onClose(Runnable) 方法。我没有尝试并从头顶写下来,但是我想到了Stream.generate(...).flatMap(file -> new BufferedReader(new InputStreamReader(new FileInputStream(file))).lines().onClose(() -> file.delete()))。不确定是否有可能,可能是因为没有关闭 BufferedReader 或检查的异常会破坏 lambda。
  • 你能解释一下为什么你不想遍历每个文件,流式传输它的行,然后删除那个文件吗?还是像您一样进行流式传输,然后删除所有文件?
  • file -> return … 不是有效的 lambda 表达式。此外,new FileInputStream(…) 要求您捕获 IOException。此外,.map(System.out::println) 不是一个有效的操作,因为println 不返回值,但您很可能希望改为执行forEach
  • 我想加载复制到特定目录的每个文件的内容。答案已经给出,我提出了一个新问题,因为我的场景不够精确:stackoverflow.com/questions/61914029/…

标签: java java-8 java-stream


【解决方案1】:

当您使用flatMap 时,函数返回的流将在处理完毕后自动关闭。您只需要在打开InputStream 时添加一个选项,指定其基础文件应在关闭时被删除。

假设localFileProvider.getNextFile() 返回java.io.File,代码如下所示

Stream.generate(localFileProvider::getNextFile)
    .takeWhile(Objects::nonNull) // stop on null, otherwise, it’s an infinite stream

// the actual operation regarding your question:
    .flatMap(file -> {
        try { return new BufferedReader(new InputStreamReader(
            Files.newInputStream(file.toPath(), StandardOpenOption.DELETE_ON_CLOSE)))
            .lines();
        } catch(IOException ex) { throw new UncheckedIOException(ex); }
    })

// the example terminal operation
    .forEach(System.out::println);

您需要使用Files.newInputStream(Path, OpenOption...) 而不是new FileInputStream(…) 来指定特殊的打开选项。所以上面的代码通过toPath()File 转换为Path;如果getNextFile() 返回String,则需要Paths.get(file)

【讨论】:

  • 真棒你的答案是正确的,有趣的是我并不想关闭文件,我想重命名它,我只是说“删除”来简化,我认为解决方案会是一样的:D
  • 我已将您的答案标记为正确,并针对我的真实场景做了一个新问题:stackoverflow.com/questions/61914029/…
猜你喜欢
  • 2021-01-26
  • 2020-09-06
  • 1970-01-01
  • 2018-01-25
  • 2023-03-21
  • 2019-06-19
  • 1970-01-01
  • 2014-01-28
  • 1970-01-01
相关资源
最近更新 更多