我想流式传输文件中包含的行,但是一旦处理完每个文件就将其移动到另一个文件夹。
当前的过程是这样的:
说明:
Stream
File
BufferedReader
flatMap
代码(为简单起见,省略了例外):
(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;
一旦每个文件都已被完全读取 ,是否可以 移动它 并继续处理流中的其他文件?
您可以将关闭动作链接到流,如果发生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很重要:
onClose
当在close()流上调用该方法时,将运行关闭处理程序,并按添加顺序执行。
close()
因此,在已经存在的关闭处理程序之后执行移动关闭处理程序,该关闭处理程序将关闭用于读取行的文件句柄。
我曾经Charset.defaultCharset()模仿new InputStreamReader(new FileInputStream(file)))问题代码的嵌套构造函数的行为,但通常情况下,应尽可能使用固定的字符集,例如Files.lines默认的UTF-8。
Charset.defaultCharset()
new InputStreamReader(new FileInputStream(file)))
Files.lines