2013-10-25 1 views
1

Моя программа собирает весь путь к файлам на компьютере (OS Ubuntu) до одного Карта. Ключ в Карта - это размер файла, а значение - это список канонического пути к файлам, размер которого равен ключу.Файлы данных Java Data StackOverflowError

Map<Long, ArrayList<String>> map = new HashMap<>(100000); 

Общее количество файлов на компьютере:

Метод, который собирает файлы, это рекурсивно.

private void scanner(String path) throws Exception { 

     File[] dirs = new File(path).listFiles(new FileFilter() { 
      @Override 
      public boolean accept(File file) { 

       if (file.isFile() && file.canRead()) { 

        long size = file.length(); 

        String canonPath = file.getCanonicalPath(); 

        if (map.containsKey(size)) 
         map.get(size).add(canonPath); 

        else map.put(size, new ArrayList<>(Arrays.asList(canonPath))); 

        return false; 
       } 
       return file.isDirectory() && file.canRead(); 
      } 
     }); 

     for (File dir : dirs) { 
      scanner(dir.getCanonicalPath()); 
     } 
    } 

Когда я начинаю начало сканирования из корневой папки «/» есть исключение:

Exception in thread "main" java.lang.StackOverflowError 
    at java.io.UnixFileSystem.canonicalize0(Native Method) 
    at java.io.UnixFileSystem.canonicalize(UnixFileSystem.java:172) 
    at java.io.File.getCanonicalPath(File.java:589) 
    at taskB.FileScanner.setCanonPath(FileScanner.java:49) 
    at taskB.FileScanner.access$000(FileScanner.java:12) 
    at taskB.FileScanner$1.accept(FileScanner.java:93) 
    at java.io.File.listFiles(File.java:1217) 
    at taskB.FileScanner.scanner(FileScanner.java:85) 
    at taskB.FileScanner.scanner(FileScanner.java:109) 
    at taskB.FileScanner.scanner(FileScanner.java:109) 
    ... 

Но для теста я заполнил каталог «~/Documents» более ~ тысяч файлов и стал от сканирования. Все работает нормально.

Почему, когда программа запускается из корневого каталога «/», где меньше 300 тысяч файлов, у меня есть исключение? Что я должен сделать, чтобы это не было?

+1

У вас есть символическая ссылка, которая создает цикл каталога? – rgettman

+1

Обратите внимание, что количество файлов не повлияет на то, вызвало ли это переполнение стека, это уровень вложенности. –

+0

@ Dennis Meng Я не знаю, может быть, исключение, потому что уровень гнездования. –

ответ

1

StackOverflow означает, что вы вызывали так много вложенных функций, что ваша программа закончила пространство в памяти для информации о вызове функции (сохраняется после возврата из вызова). В вашем случае я подозреваю, что это связано с разбором «.». (текущий каталог) и «..» (родительский каталог) при возврате в списке каталогов, таким образом, вы повторяете один и тот же каталог более одного раза.

1

Наиболее вероятным объяснением является то, что у вас есть символическая ссылка где-то в файловой системе, которая создает цикл (бесконечный цикл). Например, следующим будет цикл

/home/userid/test/data -> /home/userid 

При сканировании файлов необходимо игнорировать символические ссылки на каталоги.

1

@Jim Garrison был прав, это было связано с символическими ссылками. Решите их проблемы, я нашел here.

Использую метод isSymbolicLink(Path).

return file.isDirectory() && file.canRead() && !Files.isSymbolicLink(file.toPath()); 

 Смежные вопросы

  • Нет связанных вопросов^_^