我有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()
方法?
答案 0 :(得分:5)
创建50,000个File
对象几乎肯定不是瓶颈。实际的文件系统操作可能正在使它变慢。
我有两点建议:
答案 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
/a/a
/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)
我会为此使用特殊的数据结构。
将终端节点视为包含文件夹的文件及其父节点。您可以检查文件夹中的终端节点。如果某些文件共享相同的父文件,它将大大减少搜索操作的数量。
您的总操作次数将是
总操作=总节点 - 终端节点
简单的遍历算法你的特殊树就足够了。抱歉,但坚信这个解决方案不是基于番石榴,而是更适合。