如何同时处理多个文件?

问题描述:

我有一个场景,网络归档文件(warc)被一个爬虫周期性地放在不同的目录中。每个warc文件内部由数千个HTML文件组成。如何同时处理多个文件?

现在,我需要构建一个框架来有效地处理这些文件。我知道Java并没有按照I/O的并行处理进行扩展。我在想的是有一个监视线程扫描此目录,选择文件名并放入一个Executor服务或一些Java阻塞队列。一堆工作线程(可能是I/O问题的一小部分)在执行程序服务下进行侦听,将读取这些文件,读取其中的HTML文件并进行相应的处理。这是为了确保线程不会争夺相同的文件。

这是在性能和​​可扩展性方面的正确方法吗?另外,如何处理文件一经处理?理想情况下,文件应该被移动或标记,以便它们不会被线程再次拾取。这可以通过Future对象来处理吗?

在最近的Java版本中(从1.5开始我相信)已经在文件更改通知服务中内置了本地io库的一部分。你可能想先检查一下,而不是单独进行。请参阅here

+0

感谢您的答复。这可能有助于确定新文件是否已放入目录,但这并不能真正解决我的问题。根据要求,我需要将这些文件处理后移动到一个归档文件夹。我可以在工作完成后让工作线程移动文件,但需要通知主线程。原因是,如果工作进程发生故障,需要重新尝试重新尝试该文件。 – Shamik

+0

@ simeon..this功能在jdk 7中可用,但我仍然在jdk 6中。在做一些研究时,我发现了一个名为jpathwatch的类似库,它提供了类似的功能。我将检查它。感谢指针。 – Shamik

我的主要建议是避免重新发明车轮,除非您有特定的要求。

如果您使用的是Java 7,则可以利用WatchService(如Simeon G所建议的)。

如果您仅限于Java 6或更早版本,这些服务在JRE中不可用。但是,Apache Commons-IO提供文件监视,请参阅here

作为一个优于Java 7的优势,Commons-IO监视器将为您创建一个线程,针对已注册的回调引发事件。使用Java 7,您需要自己轮询事件列表。

一旦你有了这些事件,你建议使用ExecutorService来脱机处理文件是一件好事。移动文件由Java IO支持,您可以忽略引发的任何删除事件。

我以前用这个模型成功了。

这里有一些事情要注意:

  • 新文件事件一旦文件存在于目录中可能会得到提升。但是,数据仍将被写入它。考虑对文件大小的合理期望以及需要等到文件被认为是“整体”的时间长度

  • 您必须花费在文件上的最长时间是多少?

  • 让你执行服务参数配置通过tweakable - 这将简化您的性能测试

希望这有助于。祝你好运。

+0

@Ryan ...感谢您的指点。我在java 6中,所以不能利用WatchService。但是我看过jpathwatch,它与WatchService类似。监视器将在创建文件时引发事件。在我的情况下,生成warc文件的工具首先创建一个临时文件并向其写入数据。一旦完成,它会gzip文件。我希望,因为这是一个新的文件扩展名,侦听器将它视为一个新的文件事件。在这种情况下,我很容易跟踪。 – Shamik