【问题标题】:Efficient method to check for matching files in Java在 Java 中检查匹配文件的有效方法
【发布时间】:2012-05-17 16:57:17
【问题描述】:

我不是 Java 专家,但我正在制作的程序将处理高吞吐量问题。所以我想我会做一点众包的意见。情况是这样的。

Java 进程将监视要处理的文件的目录,这些文件将配对(要存储的数据文件和要编目的元信息的 xml 文件)。所以我需要获取当前文件的列表,检查所需的双胞胎,然后处理。

文件将始终具有匹配的文件名,并且仅在文件扩展名上有所不同,例如 文件名1.jpg 文件名1.xml 文件名2.jpg 文件名2.xml

到目前为止,我想到了三个选项。

  1. 使用 FilenameFilter 和 File.List(FileNamefilter) 调用来检查文件名的总文件是否大于 1。

  2. 使用两个文件名过滤器生成带 .xml 和不带 .xml 的文件列表,将非 XML 文件列表转换为 ArrayList 并调用 Collections.binarySearch()。

  3. 生成所有不带 .xml 扩展名的文件的列表,将此列表用作键/值对哈希映射的键,该键/值对假定基于文件名的 .xml 文件。然后遍历哈希列表并在处理前检查 .xml 孪生是否存在。

有什么想法吗?

编辑/评论

在查看了建议和修改之后,我现在使用两个 FilenameFilters,一个列出 XML 文件,一个不列出。 XML 文件列表去除了 xml 扩展名并转储到散列中。然后遍历数据文件列表,调用hashlist.contains()查看hashset中是否存在匹配项。

下面提到处理不完整文件的问题。正如我在 cmets 中所说,我假设新写入的文件在写入完成之前对非写入进程不可见(新文件,不打开编辑)

【问题讨论】:

    标签: java file filenames processing-efficiency


    【解决方案1】:

    获取所有文件,对它们进行排序,然后对文件名进行线性传递,看看哪些文件的前缀一致。显然,它们应该在排序列表中彼此相邻。

    这应该比过滤器和哈希图更简单、更快!

    要监控目录,您可能需要使用通知基础 API,例如可用时的 inotify。然后操作系统会在文件夹内容发生变化时发出信号。

    【讨论】:

      【解决方案2】:

      这有点离题了,但考虑到所陈述的意图,我希望在此处发布足够相关的内容。

      问题没有说明文件如何到达目录。如果它们通过网络或互联网进入,或者从另一个进程流式传输,则交付可​​能不是即时的,从而导致选择和处理尚未完全交付的文件的风险,例如jpeg 文件的一半。

      如果你有高吞吐量,那么如果你允许它,就会发生这种情况。即使您在处理之前短暂延迟,它也可能迟早会以某种方式发生。

      处理此问题的常用策略是传递到中间文件名(或者更好的是,相邻文件夹)。交付完成后,交付过程会将文件重命名或移动到正确的名称和位置。这一举动实际上是即时的(原子的)。对于 ftp,至少有一个众所周知的工具会自动执行这些步骤。

      如果您的部分交付的文件位于同一个文件夹中,并且仅使用备用文件扩展名进行了重命名,这可能是一个话题,这可能会影响针对此问题提到的某些选项。

      【讨论】:

      • 我的假设是,由于这些文件是新写入的,因此在写入完成之前,操作系统不会将文件显示为存在。也就是说,当目录中的新文件发生复制/写入时,任何未执行该写入的进程在查询目录中的当前文件时都看不到它。如果我错了,请纠正我。
      • 实际上,我知道的任何操作系统都会在文件创建时开始显示文件,而不是在文件关闭时(完成写入)。这就是为什么最好先写入临时文件(或临时文件夹),然后在完成后将文件移动到最终名称。
      猜你喜欢
      • 1970-01-01
      • 2011-11-03
      • 2020-05-09
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      相关资源
      最近更新 更多