Recursively find all text files in directory

2019-01-19 09:09发布

问题:

I am trying to get the names of all of the text files in a directory. If the directory has subdirectories then I also want to get any text files in those as well. I am not sure how to make the process continue for any number of subdirectories.

Right now the code below just gets all the text files in the current directory and and subdirectories in the directory. For each subdirectory found, it also finds any text files and deeper subdirectories. The problem is that if those deeper subdirectories have yet deeper subdirectories then I am not finding all the text files. This seems to be a problem that requires recursion because I don't know how deep this will go.

Here is my code so far:

File rootDirectory = new File(rootDir);
if (rootDirectory.isDirectory()) {
    System.out.println("Valid directory");

    File[] listOfFiles = rootDirectory.listFiles(); 
    for (int i = 0; i < listOfFiles.length; i++) {
        String iName = listOfFiles[i].getName();
        if (listOfFiles[i].isFile()) {
            if (iName.endsWith(".txt") || iName.endsWith(".TXT")) {
                System.out.println("File: "+iName);
            }
        }
        if (listOfFiles[i].isDirectory()) {
            System.out.println("Directory: "+iName);

            File[] subList = listOfFiles[i].listFiles();
            for (int j = 0; j < subList.length; j++) {
                String jName = subList[j].getName();
                if (subList[j].isFile()) {
                    if (jName.endsWith(".txt") || jName.endsWith(".TXT")) {
                        System.out.println("\tFile: "+jName);
                    }
                }
                if (subList[j].isDirectory()) {
                    System.out.println("\tDirectory: "+jName);
                }
            }
        }
    }
}
else System.out.println("Invalid directory");

Edit: Got it working, thank you Olaf Dietsche:

public void findFiles(File root, int depth) {
    File[] listOfFiles = root.listFiles();
    for (int i = 0; i < listOfFiles.length; i++) {
        String iName = listOfFiles[i].getName();
        if (listOfFiles[i].isFile()) {
            if (iName.endsWith(".txt") || iName.endsWith(".TXT")) {
                for (int j = 0; j < depth; j++) System.out.print("\t");
                System.out.println("File: "+iName);
            }
        }
        else if (listOfFiles[i].isDirectory()) {
            for (int j = 0; j < depth; j++) System.out.print("\t");
            System.out.println("Directory: "+iName);
            findFiles(listOfFiles[i], depth+1);
        }
    }
}

回答1:

This is a recursive problem

public void find_files(File root)
{
    File[] files = root.listFiles(); 
    for (File file : files) {
        if (file.isFile()) {
            ...
        } else if (file.isDirectory()) {
            find_files(file);
        }
    }
}


回答2:

using the java.nio.file capabilites of java 7. I implemented similiar func. and added some test.

Benchmarks when searching for .txt on my PC

            "c:/"  "c:/windows"
file.io   36272ms       14082ms
file.nio   7167ms        2987ms  

Read more in the javadoc, it's quite powerfull API

java.nio.file.filevisitor javadoc

public static void main(String[] args) {
    long starttime = System.currentTimeMillis();
    try {
        Path startPath = Paths.get("c:/");
        Files.walkFileTree(startPath, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path dir,
                    BasicFileAttributes attrs) {
                System.out.println("Dir: " + dir.toString());
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                if (file.toString().endsWith(".txt")){
                    System.out.println(file.toString());    
                }
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFileFailed(Path file, IOException e) {
                return FileVisitResult.CONTINUE;
            }
        });
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    long completetime = System.currentTimeMillis() - starttime;
    System.out.println("totaltime=" + completetime);

}


回答3:

The answer is in the tags of your question. Use recursion. Recursion consists in having a method call itself.

In this case, the method should print all the text files directly under a given directory, and call itself for every subdirectory of the directory.