malle
malle

Reputation: 334

Walking a filesystem with java recursive depth-first

i need to walk through a random filesystem(windows) with java.

The catch: it needs to walk bottom up cause i merge data together and the root should contain all of my data-sets.

That's what i have so far:

private void listDir(File dir) {
    File[] files = dir.listFiles();
    if (files != null) {
        for (int i = 0; i < files.length; i++) {
            System.out.print(files[i].getAbsolutePath());
            if (files[i].isDirectory()) {
                System.out.print(" (Directory)\n");
                listDir(files[i]);  //Recursion
            }
            else {
                System.out.print(" (File)\n");
            }
        }
    }
}

So any ideas how to realize that?

I appreciate any help and hope i don't annoy you with my questions ^^

Upvotes: 0

Views: 1887

Answers (4)

beguy
beguy

Reputation: 31

You can use java 8 lambda features like this

try (Stream<Path> walkStream = Files.walk(Paths.get("your search directory"))) {
    walkStream.forEach(f -> {
        if (f.isFile()) {
            System.out.println(f.toString() + " is file!");
        }
        //etc...
    });
}

Upvotes: 0

malle
malle

Reputation: 334

So i wrote this:

 public void walkFilesystem(File f)
{

    File[] arr= f.listFiles();
    if(arr.length>0) //-> against nullPointer
    {
        for(File file : arr)
        {
            if(file.isDirectory())
            {
                System.out.println(file.getAbsolutePath()+" (Directory)");
                walkFilesystem(file);
            }
            else if(file.isFile()&&file.getPath().contains("txt"))
            {
                System.out.println(file.getAbsolutePath()+" (node)");
            }
        }
    }

}

That should work shouldn't it?

Upvotes: 0

slim
slim

Reputation: 41223

In general, with depth-first tree recursion, you can influence the order of your output by changing the order of your output statements and recursive calls.

Take this tree:

        1
       / \
      2   3
     / \   \
    4   5   6

If my code says (all the code in this answer is pseudocode):

 void f(Node node) {
      if(node == null) return;
      print node.value;
      f(node.left);
      f(node.right);
 }

... then it will output 1 2 4 5 3 6 -- follow the logic in your head and verify this is true.

If I only change the order of the statements:

 void f(Node node) {
      if(node == null) return;
      f(node.left);
      print node.value;
      f(node.right);
 }

Now it prints 4 2 5 1 3 6 -- again, follow the logic and verify it's right.

 void f(Node node) {
      if(node == null) return;
      f(node.left);
      f(node.right);
      print node.value;
 }

... prints 4 5 2 6 3 1 -- which may be what you want.

You may want a breadth first traversal, and you may wish to reverse the order of the output - there are examples in Google.

In a filesystem there are more children than just left and right, so it would be more like:

 void recursiveList(File f) { // f could be a file or a directory
      if(f is a file) {
           output file info about f
           return
      }
      // else it's a directory
      for(File entry : f.getChildren()) {
          recursiveList(entry);
      }
      output directory info about f
  }

Upvotes: 1

aalku
aalku

Reputation: 2878

You can process, for each directory, first the subdirectories and then the files on the directory.

private void listDir(File dir) {
    File[] files = dir.listFiles();
    if (files != null) {
        for (int i = 0; i < files.length; i++) { // Directories
            if (files[i].isDirectory()) {
                System.out.print(" (Directory)\n");
                listDir(files[i]); //Recursion
            }
        }
        for (int i = 0; i < files.length; i++) { // Files
            if (!files[i].isDirectory()) {
                System.out.print(" (File)\n");
            }
        }
    }
}

Maybe you want something like this:

private int countFiles(File dir) {
    int res = 0;
    if (files != null) {
        for (int i = 0; i < files.length; i++) { // Files
            if (!files[i].isDirectory()) {
                System.out.print(" (File)\n");
                res++;
            }
        }
    }
    return res;
}
private int countFilesDeep(File dir) {
    File[] files = dir.listFiles();
    int res = 0;
    if (files != null) {
        for (int i = 0; i < files.length; i++) { // Directories
            if (files[i].isDirectory()) {
                System.out.print(" (Directory)\n");
                res += countFilesDeep(files[i]); //Recursion
            }
        }
    }
    res += countFiles(dir);
    return res;
}

Upvotes: 0

Related Questions