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

Mr.*_*art 20 java java-8 java-stream

我想流式传输文件中包含的行,但在处理后将每个文件移动到另一个文件夹。

目前的流程是这样的:

解释:

  1. 我创建StreamFile小号
  2. BufferedReader为他们每个人创建一个
  3. flatMapStreamBufferedReader
  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;
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)

重要的是onClose国家的文件

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

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

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

  • @GPI 嗯,是的。该问题没有说明这是否符合意图。如果不是,循环解决方案将会简单得多(考虑到所需异常处理的噪音,甚至比现在更简单)。 (2认同)

Krz*_*cki 6

我只想创建两种方法:

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)


Dea*_*ool 5

实际上,如果您可以将逻辑划分为不同的方法,那将非常容易

 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)