2

I have a java class for listing the files of a given directory. It works fine with directories with only files and no sub-directories. But if there is a child directory inside, it gives java.lang.StackOverflowError exception. Here is the class along with main() method:

package test;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class DisplayFilesAndFolders {

    public static void main(String[] args) {
        try {
            List<File> files = getFileList();
            for(File file : files ){
              System.out.println(file);
            }
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static List<File> getFileList() throws FileNotFoundException{
        String sPath = "C:\\Users\\owner\\Desktop\\Screen Shot\\";
        File filePath = new File(sPath);
        List<File> fileList = new ArrayList<File>();
        File[] files = filePath.listFiles();
        List<File> fileandFolderList = Arrays.asList(files);
        for (File file : fileandFolderList) {
            fileList.add(file);
            if (file.isDirectory()) {
                List<File> innerFileList = getFileList();
                fileList.addAll(innerFileList);
            }
        }

        return fileList;

    }

}

Thanks for your time.

tusar
  • 3,364
  • 6
  • 37
  • 60

2 Answers2

4

You need to take the root of the getFileList search as a parameter, and pass the subdirectory as argument each time you recurse. (Currently you're starting over at C:\Users\owner\Desktop\Screen Shot\ in each recursive call.)

Try the following (it works as intended on my system):

public class Test {

    public static void main(String[] args) {
        try {
            String root = "C:\\Users\\owner\\Desktop\\Screen Shot\\";
            List<File> files = getFileList(new File(root));
            for(File file : files ){
                System.out.println(file);
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static List<File> getFileList(File filePath)
            throws FileNotFoundException{

        List<File> fileList = new ArrayList<File>();
        File[] files = filePath.listFiles();
        List<File> fileandFolderList = Arrays.asList(files);
        for (File file : fileandFolderList) {
            fileList.add(file);
            if (file.isDirectory()) {
                List<File> innerFileList = getFileList(file);
                fileList.addAll(innerFileList);
            }
        }

        return fileList;
    }
}
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • 2
    Always remember, if you are using recursion you must have a defined stopping point. This is usually determined by the argument passed to the recursive method. If you have a recursive method that does not take any arguments it is likely you have a problem. – John B Sep 13 '11 at 15:05
  • Agree ! At first my getFileList() had a String argument, but latter i thought it will be helpful for the users to answer if I add a main() method in the class and in the long run I hardcoded it in the recursive method... :-( – tusar Sep 13 '11 at 15:16
  • @aioobe since you have helped me in the past, I request you to please have a look at my another problem. It is not related to this. http://stackoverflow.com/q/8937158/778687 – tusar Apr 03 '12 at 05:36
  • @JohnB, you too. please have a look at my another problem (not related to this) http://stackoverflow.com/q/8937158/778687 – tusar Apr 03 '12 at 05:37
1

I've implemented something like your method before, and also got a StackOverflowException, because I did not check if the File is a symbolic link. If you call isDirectory on a symbolic link which points to a directory, it will return true. Thus, you will follow the symbolic link, which can point to anywhere, maybe resulting in an endless tree traversal, resulting in a StackOverflowException.

helpermethod
  • 59,493
  • 71
  • 188
  • 276
  • can you give an example of "symbolic link" ? – tusar Sep 13 '11 at 15:19
  • 2
    unix> man ln Look for the -s flag. When you "ls -l" they look like this: a --> some/other/dir/a The arrow is the key. – Chris Sep 13 '11 at 15:22
  • An article that describes how to create symbolic links in Windows so you can see how your code handles them: http://www.windows7home.net/how-to-create-symbolic-link-in-windows-7/ –  Sep 15 '11 at 15:40
  • @Phoenix, and Oliver Weiler, could you please have a look at my another problem (not related to this). I need help from you guys. Thanks for your time. http://stackoverflow.com/q/8937158/778687 – tusar Apr 03 '12 at 05:41