Java 如何遍历庞大目录的目录树并忽略文件

Java 如何遍历庞大目录的目录树并忽略文件,java,performance,java-web-start,filewalker,Java,Performance,Java Web Start,Filewalker,我需要在网络驱动器上遍历一个目录,并在层次结构中创建一个从子目录到父目录的映射。一个具有代表性的目录是6TerraBytes,有900000个文件和900个文件夹。我只关心文件夹,不关心文件。出于测试目的,我将没有文件的文件夹复制到另一个网络驱动器,并在复制的版本上运行代码。只需迭代900个文件夹可能需要10秒钟。但是,在原始目录结构上迭代需要30分钟。看起来我们正在遍历所有900000个文件,尽管我们只是忽略了它们 有没有办法通过不看文件来加快速度?如果可以的话,我更愿意使用纯Java。当通过

我需要在网络驱动器上遍历一个目录,并在层次结构中创建一个从子目录到父目录的映射。一个具有代表性的目录是6TerraBytes,有900000个文件和900个文件夹。我只关心文件夹,不关心文件。出于测试目的,我将没有文件的文件夹复制到另一个网络驱动器,并在复制的版本上运行代码。只需迭代900个文件夹可能需要10秒钟。但是,在原始目录结构上迭代需要30分钟。看起来我们正在遍历所有900000个文件,尽管我们只是忽略了它们

有没有办法通过不看文件来加快速度?如果可以的话,我更愿意使用纯Java。当通过Windows资源管理器浏览这个巨大的目录时,它一点也不觉得慢。我的代码如下

public static Map<String, String> findFolderPaths(File parentFolder) throws IOException {
        Map<String, String> parentFolderMap = new HashMap<String, String>();
        Files.walkFileTree(parentFolder.toPath(), new FolderMappingFileVisitor(parentFolderMap));

        return parentFolderMap;
    }


static class FolderMappingFileVisitor extends SimpleFileVisitor<Path> {
        private Map<String, String> mapping;
        FolderMappingFileVisitor(Map<String, String> map) {
            this.mapping = map;
        }
        @Override
        public FileVisitResult preVisitDirectory(Path dir,
                BasicFileAttributes attrs) throws IOException {
            File directory = dir.toFile();
            mapping.put(directory.getName(), directory.getParent());

            return FileVisitResult.CONTINUE;
        }
    }
公共静态映射FindFolderPath(文件父文件夹)引发IOException{
Map parentFolderMap=newhashmap();
walkFileTree(parentFolder.toPath(),新的FolderMappingFileVisitor(parentFolderMap));
返回父文件夹映射;
}
静态类FolderMappingFileVisitor扩展了SimpleFileVisitor{
私人地图测绘;
FolderMappingFileVisitor(地图){
this.mapping=map;
}
@凌驾
公共文件VisitResult preVisitDirectory(路径目录,
BasicFileAttributes(属性属性)引发IOException{
File directory=dir.toFile();
mapping.put(directory.getName(),directory.getParent());
返回FileVisitResult.CONTINUE;
}
}
编辑:


我没有提到的一个重要问题是,我们正在webstart中运行该应用程序。我报告的时间是从生产,而不是开发。从Eclipse运行时,时间比我对FileWalker的期望要长。

您使用的方法是获取基本文件属性,我怀疑它正在访问每个文件的文件描述信息

如果您只需要名称,我建议您反复/递归地调用File.listFiles();这应该只获得你要求的信息

差不多

public static Map<String, String> findFolderPaths(File parentFolder) throws IOException {
    Map<String, String> map = new HashMap<String, String>();
    findFolderPaths(parentFolder, map);
    return map;
}

public static void findFolderPaths(File dir, Map<String, String> map) throws IOException {
    map.put(dir.getName(), dir.getPparent());
    for(File file : dir.listFiles())
        if (file.isDirectory())
            findFolderPaths(file, map);
}
公共静态映射FindFolderPath(文件父文件夹)引发IOException{
Map Map=newhashmap();
FindFolderPath(父文件夹、映射);
返回图;
}
公共静态void findFolderPath(文件目录,映射映射)引发IOException{
put(dir.getName(),dir.getPparent());
对于(文件:dir.listFiles())
if(file.isDirectory())
FindFolderPath(文件、地图);
}

如您所见,它不会做任何您不需要它做的事情。

文件漫游器的工作速度似乎比file.listFiles()快得多。问题似乎是JavaWebStart。当我在JavaWebStart下运行应用程序时,大约需要30分钟。当我从Eclipse运行应用程序时,需要几分钟的时间。JavaWebStart正在扼杀我们的性能


这个应用程序是一个数据/io密集型应用程序,我注意到过去在Webstart下运行这个应用程序时存在其他问题。解决方案是从Java Webstart迁移出去。

感谢您的回复。我最初是为Java6编写的,您的代码就是我最初的代码。我认为FileWalker速度更快,但实际上还没有计时。我的计时现在给我带来了令人困惑的结果,因此我正在进一步研究它。这可能是因为Java Webstart应用程序使用SecurityManager来检查对每个文件的访问,而当您从Eclipse运行时,您可能没有启用SecurityManager。如果这仍然是一个问题,并且没有安全问题,您可以尝试禁用Webstart配置中的相关安全设置。