【发布时间】:2020-10-05 17:06:31
【问题描述】:
在 Java 中,这是处理特定目录中文件“快照”的几种方法之一:
String directory = "/path/to/directory";
List<File> fileList = Arrays.asList((new File(directory)).listFiles());
fileList.parallelStream.forEach(file->{
Path fileAsPath = file.toPath();
// Assume the process method finishes by deleting the file or moving it to another directory
process(fileAsPath);
});
这是处理添加到目录中的文件的几种方法之一:
WatchService watchService = FileSystems.getDefault().newWatchService();
Path directoryAsPath = Paths.get(directory);
WatchKey watchKey = directoryAsPath.register(watchService, ENTRY_CREATE);
while (true) {
WatchKey key;
key = watchService.take();
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
if (kind == OVERFLOW) {
continue;
}
Path filename = event.context();
// Again, assume the process method finishes by deleting the file or moving it
// to another directory
process(filename);
}
}
什么是处理目录中预先存在的文件(例如进程何时开始)以及处理随后添加的文件的相当简单的方法?
每个文件都应该只处理一次。在这种情况下,处理文件的顺序无关紧要。
我想一种直接的方法是将第一个逻辑块放入无限循环中——只需让 listFiles() 方法拍摄目录的新快照,可能在迭代之间有短暂的延迟 -= 但这似乎笨重。文件的大小可能为数十兆字节。在开始另一个文件“快照”之前不必等待文件的整个“快照”被完全处理,这将是一件好事。
使用数据库来跟踪已处理的文件似乎过于复杂。
谢谢!
【问题讨论】:
-
你在哪个操作系统上?
-
我不明白这个问题。当您说“处理方法通过删除文件或将其移动到另一个目录来完成”时,不可能对文件进行两次处理。
-
@Holger 每个文件的大小可以是数兆字节。处理它可能需要一些时间——在此期间可能会再次尝试处理它。嗯...也许一种解决方法是,作为预处理操作,将文件移动到一个唯一的临时目录,将在其中处理它。
-
你展示了一个循环。处理一个接一个文件时,处理不能重叠。
-
有两个循环:(1)处理预先存在的文件的循环,和(2)处理新添加的文件的循环。我想确保每个文件只处理一次。我假设每个都需要在单独的线程中运行 - 否则,两个循环可能会丢失一些文件。使用不同的线程,两个线程可能会尝试处理同一个文件。
标签: java java-stream nio file-processing