Mr.*_*art 20 java java-8 java-stream
我想流式传输文件中包含的行,但在处理后将每个文件移动到另一个文件夹。
目前的流程是这样的:
解释:
Stream的File小号BufferedReader为他们每个人创建一个flatMap到Stream了BufferedReader代码(为简单起见省略了例外):
(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;
Run Code Online (Sandbox Code Playgroud)
一旦完全读取每个文件并继续处理流中的其他文件,是否可以移动每个文件?
Hol*_*ger 15
您可以将关闭操作链接到流,在以下情况下将自动执行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);
Run Code Online (Sandbox Code Playgroud)
关闭处理程序
close()在流上调用方法时运行,并按添加顺序执行。
因此,移动关闭处理程序在已经存在的关闭处理程序之后执行,该关闭处理程序将关闭用于读取行的文件句柄。
我曾经Charset.defaultCharset()模仿new InputStreamReader(new FileInputStream(file)))您的问题代码的嵌套构造函数的行为,但通常,您应该使用固定字符集,例如尽可能使用Files.lines的默认 UTF-8。
我只想创建两种方法:
public void processFile(File f);
public void moveFile(File f, File dstFolder);
Run Code Online (Sandbox Code Playgroud)
然后在 lambda 中:
Stream.generate(localFileProvider::getNextFile).forEach(file->
{
processFile(file);
moveFile(file, dstFolder)
}
}
Run Code Online (Sandbox Code Playgroud)
实际上,如果您可以将逻辑划分为不同的方法,那将非常容易
public Path readFile(File eachFile) {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
//try-with-resources
try (Stream<String> lines = reader.lines()) {
lines.forEach(System.out::println);
}
catch (IOException e) {
e.printStackTrace();
}
return eachFile.toPath();
}
Run Code Online (Sandbox Code Playgroud)
然后为每个文件调用这个方法
(1) Stream.generate(localFileProvider::getNextFile)
(2) .map(this::readFile) //process each file
(3) .forEach(path->Files.move(path,Paths.get("new path"))); //then move each file
Run Code Online (Sandbox Code Playgroud)