如何检查给定路径列表中是否存在文件?

时间:2012-06-15 07:59:23

标签: java file file-io guava

我有50,000个路径的列表,我需要检查每个路径是否存在文件。现在,我正在独立验证每条路径:

public static List<String> filesExist(String baseDirectory, Iterable<String> paths) throws FileNotFoundException{
        File directory = new File(baseDirectory);
        if(!directory.exists()){
            throw new FileNotFoundException("No Directory found: " + baseDirectory );
        }else{
            if(!directory.isDirectory())
                throw new FileNotFoundException(baseDirectory + " is not a directory!");
        }

        List<String> filesNotFound = new ArrayList<String>();

        for (String path : paths) {
            if(!new File(baseDirectory + path).isFile())
                filesNotFound.add(path);
        }
        return filesNotFound;
    }

有没有办法改进它,以便我不创建50,000个File对象?我也在用番石榴。是否有任何实用程序可以帮助我使用批量exists()方法?

5 个答案:

答案 0 :(得分:5)

创建50,000个File对象几乎肯定不是瓶颈。实际的文件系统操作可能正在使它变慢。

我有两点建议:

  1. 在检查之前,按路径按位置对路径进行排序,以充分利用文件系统缓存。
  2. 如果子目录不存在,您可以自动假设其中的所有文件和子目录也不存在。

答案 1 :(得分:0)

我同意aix之前的回答,但我想补充一点观点。假设文件系统访问是瓶颈而 IF ,baseDirectory下的文件数量大致已知且不太大(无论这意味着什么),可能值得尝试FileUtils.iterateFiles或{{1然后检查路径中是否存在每个返回的路径。这背后的想法是,这些方法执行的目录列表可能比许多单独的访问更有效。

同样,这种方法取决于对您的环境的一些假设,但总是值得给它一个想法并试一试。

(希望将其添加为对aix的回复的评论,但不能......)

答案 2 :(得分:0)

恕我直言,一个非常有效的解决方案(灵感来自之前的答案)如下:

  • 对路径进行排序
  • 将每个人视为树
  • 另一棵树是目录树
  • 访问目录树时读取整个目录以防其他树中有“很多”子项,否则使用单独检查“少数”子项
  • 对两棵树进行平行遍历,跳过其中一棵缺失的部分

示例(作为预订单列表提供的树):

tree1: / /a /a/a /d /d/a /d/a/b /e
tree2: / /a /b /d /d/a /e

处理:

  • /
  • 开始
  • 从此出现在/a
  • 在tree2
  • 中跳过/a/a
  • 在tree1
  • 中跳过/b
  • 从此出现在/d
  • ...

您的filesNotFound列表包含树中与输入列表对应的所有文件。

答案 3 :(得分:0)

由于原因,我现在无法启动我的开发环境,所以这可能稍微不正确。 Go-go小工具功能编程!

public static List<String> filesExist(String baseDirectory, Iterable<String> paths) throws FileNotFoundException{
    final File base = new File(baseDirectory);
    if (base.exists()) {
        return FluentIterable.from(paths).filter(new Predicate<String>() {
            public boolean apply(String in) {
                return new File(in,base).exists();
            }
        }).toImmutableList();
    }
    throw new FileNotFoundException("Base doesn't exist!");
}

如上所述,您的主要问题仍然是I / O.

答案 4 :(得分:0)

我会为此使用特殊的数据结构。

TRIE

enter image description here

将终端节点视为包含文件夹的文件及其父节点。您可以检查文件夹中的终端节点。如果某些文件共享相同的父文件,它将大大减少搜索操作的数量。

您的总操作次数将是

总操作=总节点 - 终端节点

简单的遍历算法你的特殊树就足够了。抱歉,但坚信这个解决方案不是基于番石榴,而是更适合。