一尘不染

流式传输文件并在读取后移动它们

java

我想流式传输文件中包含的行,但是一旦处理完每个文件就将其移动到另一个文件夹。

当前的过程是这样的:

说明:

  1. 我创建StreamFile小号
  2. BufferedReader为他们每个人创建一个
  3. flatMap到线StreamBufferedReader
  4. 我打印每一行。

代码(为简单起见,省略了例外):

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

一旦每个文件都已被完全读取 ,是否可以 移动它 并继续处理流中的其他文件?


阅读 310

收藏
2020-12-03

共1个答案

一尘不染

您可以将关闭动作链接到流,如果发生flatMap以下情况,该动作将自动执行:

Stream.generate(localFileProvider::getNextFile).takeWhile(Objects::nonNull)

    .flatMap(file -> {
        try {
            Path p = file.toPath();
            return Files.lines(p, Charset.defaultCharset()).onClose(() -> {
                try { // move path/x/y/z to path/x/y/z.moved
                    Files.move(p, p.resolveSibling(p.getFileName()+".moved"));
                } catch(IOException ex) { throw new UncheckedIOException(ex); }
            });
        } catch(IOException ex) { throw new UncheckedIOException(ex); }
    })

    .forEach(System.out::println);

状态文档onClose很重要:

当在close()流上调用该方法时,将运行关闭处理程序,并按添加顺序执行。

因此,在已经存在的关闭处理程序之后执行移动关闭处理程序,该关闭处理程序将关闭用于读取行的文件句柄。

我曾经Charset.defaultCharset()模仿new InputStreamReader(new FileInputStream(file)))问题代码的嵌套构造函数的行为,但通常情况下,应尽可能使用固定的字符集,例如Files.lines默认的UTF-8。

2020-12-03