【问题标题】:How can I process multiple files concurrently?如何同时处理多个文件?
【发布时间】:2011-09-23 03:02:15
【问题描述】:

我有一个场景,其中网络存档文件 (warc) 被爬虫定期删除到不同的目录中。每个 warc 文件内部包含数千个 HTML 文件。

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

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

【问题讨论】:

    标签: java multithreading file concurrency io


    【解决方案1】:

    在最近的 Java 版本中(我相信从 1.5 开始),已经内置了文件更改通知服务,作为本机 io 库的一部分。您可能想先检查一下,而不是自己动手。见here

    【讨论】:

    • 感谢您的回复。这可能有助于确定新文件是否已放入目录中,但这并不能真正解决我的问题。根据要求,处理完文件后,我需要将文件移动到存档文件夹。一旦完成,我可以让工作线程执行文件移动,但这需要通知主线程。原因是,如果工作进程失败,则需要再次重试该文件。跨度>
    • @simeon..此功能在 jdk 7 中可用,但我仍在 jdk 6 中。在做一些研究时,我发现了类似的名为 jpathwatch 的库,它提供了类似的功能。我会检查一下出去。谢谢指点。
    【解决方案2】:

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

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

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

    与 Java 7 相比,Commons-IO 监视器会为您创建一个线程,该线程会针对已注册的回调引发事件。在 Java 7 中,您需要自己轮询事件列表。

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

    我过去曾成功使用过这个模型。

    以下几点需要注意:

    • 一旦目录中存在文件,可能会引发新文件事件。但是,数据仍将被写入其中。考虑对文件大小的合理预期以及您需要等待多长时间才能将文件视为“完整”

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

    • 通过配置使您的执行器服务参数可调整 - 这将简化您的性能测试

    希望这会有所帮助。祝你好运。

    【讨论】:

    • @Ryan ...感谢您的指点。我在java 6中,所以不能利用WatchService。但我确实看过jpathwatch,它类似于WatchService。监视器将在创建文件时引发事件。就我而言,生成warc文件的工具首先创建一个临时文件并将数据写入其中。完成后,它将 gzip 文件。我希望由于这是一个新的文件扩展名,侦听器会将其视为新文件事件。在这种情况下,我很容易跟踪。
    猜你喜欢
    • 2018-11-19
    • 1970-01-01
    • 2021-03-05
    • 2011-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多