搜索多个文件夹的大型目录 - JAVA

时间:2015-11-26 11:08:22

标签: java search directory subdirectory

我希望能够搜索大型目录,包括名为“在线”的每个文件夹的所有子文件夹,并将找到的文件夹添加到列表中。

换句话说:这个文件是文件夹吗?如果不是忽略,如果是,这个文件夹名为“在线”?,如果是,则添加到列表,如果没有打开并循环浏览文件夹内容并重新开始。

我有一个脚本:

String fileType = "online";

private void buildList(File aFile) {
 if (aFile.isDirectory()) {

    if (fileName.contains(fileType)) {
        addToList(aFile);
    } else {
        for (File bFile : aFile.listFiles()) {
            buildList(bFile);
        }
    }
 }
}

这适用于小目录但不适用于大型目录,因为它已打开大量数组。它会挂起并耗尽所有内存。

我对所有建议持开放态度。仅JAVA和理想的JDK1.6兼容。非常感谢你提前!!!!

编辑:

static long counter = 0L;
ArrayList<File> opFolders;


public final class DirectoryCollectorVisitor extends SimpleFileVisitor<Path> {

   private final List<Path> list;



   public DirectoryCollectorVisitor(final List<Path> list) {


      this.list = list;
    }

    @Override
    public FileVisitResult preVisitDirectory(final Path path, final BasicFileAttributes attrs) {
        counterPrintField.setText("" + counter++);
        if (path.getFileName().toString().contains("online")) {
            list.add(path);
            File aFile = path.toFile();
            opFolders.add(aFile);
        }
        return FileVisitResult.CONTINUE;
    }
}



private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {                                           

    JFileChooser chooser = jFileChooser1;
    chooser.setCurrentDirectory(new java.io.File("O:\\Prod\\Clients"));
    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    chooser.setAcceptAllFileFilterUsed(false);
    int returnVal = chooser.showOpenDialog(this);

    if (returnVal == chooser.APPROVE_OPTION) {
        File file = chooser.getSelectedFile();
        try {
            jTextArea1.setText(null);
            opFolders = new ArrayList<>();

            final Path baseDir = Paths.get(file.getAbsolutePath());
            final List<Path> dirList = new ArrayList<>();
            dirList.add(baseDir);

            final FileVisitor<Path> visitor = new DirectoryCollectorVisitor(dirList);
            Files.walkFileTree(baseDir, visitor);
            if(opFolders.isEmpty()){
                System.err.println("EMPTY");
            }
            for (File aFile : opFolders) {
                if (!aFile.isDirectory() && !aFile.getName().toLowerCase().endsWith(".db")) {
                    jTextArea1.append(aFile.getAbsolutePath() + "\n");

                }

            }

            jTextArea1.append("...COMPLETE...");
        } catch (Exception ex) {
            System.out.println("Problem accessing directory: " + file.getAbsolutePath());
        }
    } else {
        System.out.println("File access cancelled by user.");
    }

}

@fge更新代码

1 个答案:

答案 0 :(得分:0)

不幸的是,你说你只限于Java 6.鉴于这个要求,没有办法使用File API来做到这一点。 .listFiles()只能以热切的方式填充目录条目。

好吧,有一种方法......如果您使用类似Unix的操作系统,您可以使用ProcessBuilder并使用find -type d -name online之类的命令从基本目录发出进程:< / p>

final File baseDir = ...;
final ProcessBuilder pb = new ProcessBuilder(
    "find", "-type", "d", "-name", "online"
);
pb.directory(baseDir);

final Process p = pb.start();
// use the Process' InputStream

如果你使用Java 7+,你会有更轻松的时间;对FileVisitor进行编程以收集到列表中:

public final class DirectoryCollectorVisitor
    extends SimpleFileVisitor<Path>
{
    private final List<Path> list;

    public DirectoryCollectorVisitor(final List<Path> list)
    {
        this.list = list;
    }

    @Override
    public FileVisitResult previsitDirectory(final Path path, final BasicFileAttributes attrs)
    {
        if (path.getFileName().toString().equals("online"))
            list.add(path);
        return FileVisitResult.CONTINUE;
    }
}

// ...

final Path baseDir = Paths.get(...);
final List<Path> dirList = new ArrayList<>();
final FileVisitor<Path> visitor = new DirectoryCollectorVisitor(list);
Files.walkFileTree(baseDir, visitor);
// dirList is not filled with the entries

使用Java 8,它更加简单:

private static final BiPredicate<Path, BasicFileAttributes> ONLINE_DIRS 
    = (path, attrs) -> attrs.isDirectory() 
    && path.getFileName().toString().equals("online");

// ...

final Path baseDir = Paths.get(...);
final List<Path> dirList;

try (
    final Stream<Path> stream = Files.find(baseDir, Integer.MAX_VALUE,
        ONLINE_DIRS);
) {
    dirList = stream.collect(Collectors.toList());
}