我遇到的一种情况是,爬网程序会定期将Web存档文件(warc)放在不同的目录中。每个warc文件内部包含数千个HTML文件。
现在,我需要构建一个框架来有效地处理这些文件。我知道Java在I / O的并行处理方面无法扩展。我在想的是拥有一个监视线程,该线程可以扫描该目录,选择文件名,然后放入Executor服务或某些Java阻止队列。在执行程序服务下侦听的一堆工作线程(可能是少数I / O问题)将读取文件,读取其中的HTML文件并进行相应的处理。这是为了确保线程不会争用同一文件。
就性能和可伸缩性而言,这是正确的方法吗?另外,一旦处理完文件,如何处理?理想情况下,应移动或标记文件,以免线程再次拾取它们。可以通过Future对象处理吗?
我的主要建议是除非有特殊要求,否则避免重新发明轮子。
如果您使用的是Java 7,则可以利用WatchService(如Simeon G所建议)。
如果限于Java 6或更早版本,则JRE中不提供这些服务。但是,Apache Commons-IO提供文件监视。请参见此处。
作为与Java 7相比的一项优势,Commons-IO监视器将为您创建一个线程,该线程针对已注册的回调引发事件。使用Java 7,您将需要自己轮询事件列表。
一旦发生事件,建议使用ExecutorService处理线程外文件是一个很好的建议。 Java IO支持移动文件,您可以忽略任何引发的删除事件。
我过去曾成功使用过这种模型。
这里有一些注意事项:
一旦文件存在于目录中,就可能引发新文件事件。但是,数据仍将被写入其中。考虑对文件大小的合理预期,以及直到文件被视为"完整"需要等待多长时间
您必须在文件上花费的最长时间是多少?
通过配置使执行程序服务参数可调整-这将简化性能测试
希望这可以帮助。祝好运。
@Ryan ...感谢您的指导。我在Java 6中无法使用WatchService,但是我确实看过jpathwatch,它类似于WatchService。创建文件时,监视器将引发事件。就我而言,生成warc文件的工具首先创建一个临时文件,然后向其中写入数据。完成后,它将gzip文件压缩。我希望这是一个新的文件扩展名,因此侦听器会将其视为新的文件事件。在这种情况下,对我来说很容易跟踪。
在Java的最新版本(我相信从1.5开始)中,已经将内置的文件更改通知服务作为本机io库的一部分。您可能需要先检查一下,而不要自己检查。看这里
感谢您的答复。这可能有助于确定是否将新文件拖放到目录中,但这并不能真正解决我的问题。根据要求,处理完文件后,我需要将文件移动到存档文件夹中。我可以让工作线程一旦完成就进行文件移动,但是这需要通知主线程。原因是,如果工作进程失败,则需要再次重试该文件。
@simeon ..此功能在jdk 7中可用,但我仍然在jdk 6中。在做一些研究后,我发现了一个名为jpathwatch的相似库,它提供了相似的功能。请检查一下。感谢您的指导。