14

I am trying to get a list of all files in a directory and its subdirectories. My current recursive approach is as follows:

private void printFiles(File dir) {
  for (File child : dir.listFiles()) {
    if (child.isDirectory()) {
      printFiles(child);
    } else if (child.isFile()) {
      System.out.println(child.getPath());
    }
  }
}

printFiles(new File("somedir/somedir2"));

However, I was hoping there was a non-recursive way (an existing API call, maybe) of doing this. If not, is this the cleanest way of doing this?

K Mehta
  • 10,323
  • 4
  • 46
  • 76
  • 5
    possible duplicate of [Recursively list files in Java](http://stackoverflow.com/questions/2056221/recursively-list-files-in-java). The title says recursively, but the first answer is a library call. – Jacob Jul 21 '11 at 12:47
  • @cularis Not a duplicate, as I'm trying to do it non-recursively, whereas the other SO question is asking for it to be done recursively. – K Mehta Jul 21 '11 at 12:49
  • What's wrong with recursion? There's no API for this, however you can still do it with a `while` loop and some funny other business, but it will be messy. – Aleks G Jul 21 '11 at 12:49
  • 2
    @Kshitij Read the full comment and the answer before replying. – Jacob Jul 21 '11 at 12:50
  • @Aleks There is an api for this – RMT Jul 21 '11 at 12:50
  • In C# you could do a pattern match (basically a search) within the directory and that would pull back everyhting recursively that matches ... assuming you searched for "*.*" you would get all files. Not sure how that works in java though. – War Jul 21 '11 at 12:50
  • @cularis: I did read the whole comment before you modified it :) – K Mehta Jul 21 '11 at 12:51
  • Then you didn't read the question/answers. ;) – Jacob Jul 21 '11 at 12:51
  • @RMT What's the class/method? – Aleks G Jul 21 '11 at 12:53
  • 1
    Either way, I do believe this question provides value to the community as someone searching for it, at first glance, will ignore the other question (like I did) because of the title – K Mehta Jul 21 '11 at 12:53
  • @Aleks check answer or the linked question + this answer – RMT Jul 21 '11 at 12:54

3 Answers3

31

You can always replace a recursive solution with an iterative one by using a stack (for DFS) or a Queue (For BFS):

private void printFiles(File dir) {
  Stack<File> stack = new Stack<File>();
  stack.push(dir);
  while(!stack.isEmpty()) {
    File child = stack.pop();
    if (child.isDirectory()) {
      for(File f : child.listFiles()) stack.push(f);
    } else if (child.isFile()) {
      System.out.println(child.getPath());
    }
  }
}

printFiles(new File("abc/def.ghi"));
Muskovets
  • 449
  • 8
  • 16
Ryan Gross
  • 6,423
  • 2
  • 32
  • 44
  • Sometimes I dislike how long it takes for Eclipse to start. Well done. I am very surprised at why some engineers would wonder why recursion can be bad, and why using a Stack would of been messy. – Andrew T Finnell Jul 21 '11 at 13:00
  • The stack approach looks better than the recursive approach, thanks! – K Mehta Jul 21 '11 at 13:27
  • 1
    How is the stack approach better? Sure it might be a little faster but recursion is very simple and elegant. Internally, recursion uses a stack anyways. – tskuzzy Jul 21 '11 at 13:41
  • 2
    Both, speed, and the fact that recursion has to store the state of the entire function (which has been stripped down in my question for the purpose of posting it on SO) on the stack, whereas with this approach, I am only saving the File objects on the stack – K Mehta Jul 21 '11 at 13:57
  • Hey this is perfect, can we restrict tht it goes only to depth 2 or 5... like some number not more than that. – silentsudo Oct 24 '17 at 18:39
  • That's exactly what I'm looking for. Thank you bro – Đốc.tc Oct 15 '21 at 09:49
4

Java 8 onward, you can use Files#walk to list out all files and directories recursively in a given directory. Further you can apply the filter like Files::isRegularFile to filter out the directories if you need only regular files.

On the flip side, if you only need to list the given directory but not its sub-directories, you can use the lazy method Files#list which will only give you the files and directories in the given directory. You can again further apply the filter mentioned above.

VHS
  • 9,534
  • 3
  • 19
  • 43
3

FileUtils Is probably the best way to go. (COPY OF THE LINKED QUESTION) only posted so people searching this will see it and will probably not read the comments

edit: Methods to be used Listfiles

Community
  • 1
  • 1
RMT
  • 7,040
  • 4
  • 25
  • 37
  • Maybe I'm missing something, but I was looking at the FileUtils documentation, and there's a note under the constructor which says "Instances should NOT be constructed in standard programming." – K Mehta Jul 21 '11 at 12:58
  • 1
    yes.. Instances... you should use the static methods they provide. (btw they are almost all static) – RMT Jul 21 '11 at 12:59
  • Ran into another issue; Eclipse doesn't recognize the FileUtils class. Which package should I be importing? – K Mehta Jul 21 '11 at 13:15
  • Ahh, looks like I can't use it after all. Don't have the option of installing additional libraries. But thanks anyway! – K Mehta Jul 21 '11 at 13:26
  • It's a part of a Distributed File System assignment for school, and the machines the code will be tested on does not have the apache commons library installed. – K Mehta Jul 21 '11 at 13:54