2010-04-05 8 views
5

Перед тем, как отладить функцию рекурсивной функции с поздним вылетом: есть ли команда для получения субдиров? giveMeSubDirs(downToPath)?Java: как получить все поддиры рекурсивно?

// WARNING: RECURSION out of bound or too much data 
public HashSet<FileObject> getAllDirs(String path) { 
    HashSet<FileObject> checkedDirs = new HashSet<FileObject>(); 
    HashSet<FileObject> allDirs = new HashSet<FileObject>(); 

    String startingPath = path; 

    File fileThing = new File(path); 
    FileObject fileObject = new FileObject(fileThing); 

    for (FileObject dir : getDirsInDir(path)) { 

    // SUBDIR 

    while (!checkedDirs.contains(dir) 
     && !(getDirsInDir(dir.getFile().getParent()).size() == 0)) { 

     // DO NOT CHECK TOP DIRS if any bottom dir UNCHECKED! 

     while (uncheckedDirsOnLevel(path, checkedDirs).size() > 0) { 

     while (getDirsInDir(path).size() == 0 
      || (numberOfCheckedDirsOnLevel(path, checkedDirs)==getDirsInDir(path).size())) { 
      allDirs.add(new FileObject(new File(path))); 
      checkedDirs.add(new FileObject(new File(path))); 

      if(traverseDownOneLevel(path) == startingPath) 
      return allDirs; 

      //get nearer to the root 
      path = traverseDownOneLevel(path); 
     } 
     path = giveAnUncheckedDir(path, checkedDirs); 

     if (path == "NoUnchecked.") { 
      checkedDirs.add(new FileObject((new File(path)).getParentFile())); 
      break; 
     } 
     } 
    } 
    } 
    return allDirs; 
} 

Резюме о коде:

  1. Перейти так глубоко в дереве каталогов, как это возможно. Когда в режке нет директории, остановитесь, поставьте рекордер в комплект, перейдите. Не проверяйте dirs в комплекте.
  2. Остановите и верните комплект, если вы достигнете начального пути.
  3. Повторите шаги 1 и 2.

предпосылки: каталог-структура является конечной и с небольшим количеством данных.

+0

ИМО лучше идти сверху вниз, а затем снизу вверх (как в моем решении ниже :)). Это более естественно, и вам не нужно сохранять пути на промежуточных уровнях. – pajton

+0

Что вы пытаетесь сделать? Вы пытаетесь перечислить все подкаталоги, пока не достигнете определенного уровня? – OscarRyz

+1

В названии говорится: «рекурсивно», но в вашем коде не рекурсивно? Вы ищете рекурсивное решение или для нерекурсивного решения? Полное имя для «FileObject» - это 'javax.tools.FileObject' – OscarRyz

ответ

23

Вы можете получить все подкаталоги со следующим фрагментом:

File file = new File("path"); 
File[] subdirs = file.listFiles(new FileFilter() { 
    public boolean accept(File f) { 
     return f.isDirectory(); 
    } 
}); 

Это получает только непосредственные подкаталоги, чтобы получить все из них рекурсивно вы могли бы написать:

List<File> getSubdirs(File file) { 
    List<File> subdirs = Arrays.asList(file.listFiles(new FileFilter() { 
     public boolean accept(File f) { 
      return f.isDirectory(); 
     } 
    })); 
    subdirs = new ArrayList<File>(subdirs); 

    List<File> deepSubdirs = new ArrayList<File>(); 
    for(File subdir : subdirs) { 
     deepSubdirs.addAll(getSubdirs(subdir)); 
    } 
    subdirs.addAll(deepSubdirs); 
    return subdirs; 
} 
+0

+1, быстрее меня! – Jack

+0

Thnx, довольно необычная поддержка :-) – pajton

+0

Мне это нравится, очень чистый –

2

Нет, такой функциональности в стандартном API Java нет. Но есть в Apache commons-io; если вы не хотите включать его в качестве библиотеки, вы также можете указать look at the source code.

-1
class DirFileFilter extends FileFilter { 
    boolean accept(File pathname) { 
    return pathname.isDirectory(); 
    } 
} 

DirFileFilter filter = new DirFileFilter(); 
HashSet<File> files = new HashSet<File>(); 

void rec(File root) { 
    // add itself to the list 
    files.put(root); 
    File[] subdirs = root.list(filter); 

    // bound of recursion: must return 
    if (subdirs.length == 0) 
    return; 
    else //this is the recursive case: can call itself 
    for (File file : subdirs) 
     rec(file); 
} 
+0

Что-то не так с компиляцией: http://stackoverflow.com/questions/2581158/java-how-to-get-all-subdirs-recursive/2584464#2584464 – hhh

2

Другая версия с нет рекурсии и алфавитного порядка. Также используется Set, чтобы избежать циклов (проблема в Unix-системах со ссылками).

public static Set<File> subdirs(File d) throws IOException { 
     TreeSet<File> closed = new TreeSet<File>(new Comparator<File>() { 
      @Override 
      public int compare(File f1, File f2) { 
       return f1.toString().compareTo(f2.toString()); 
      } 
     }); 
     Deque<File> open = new ArrayDeque<File>(); 
     open.push(d); 
     closed.add(d); 
     while (! open.isEmpty()) { 
      d = open.pop(); 
      for (File f : d.listFiles()) { 
       if (f.isDirectory() && ! closed.contains(f)) { 
        open.push(f); 
        closed.add(f); 
       } 
      } 
     } 
     return closed; 
    } 
+1

На самом деле вам не следует использовать класс java.util.Stack, как он сломан. Вместо этого используйте ArrayDeque: Deque stack = new ArrayDeque (); – helpermethod

+0

Хороший звонок. Вместо этого я отредактировал код, чтобы использовать Deques. – tucuxi

+0

Разбито как, из интереса? Просто интересно :) –

1

Отсутствует образец кода ");" в конце заявления. Правильный код должен быть:

File file = new File("path"); 
    File[] subdirs = file.listFiles(new FileFilter() { 
     public boolean accept(File f) { 
      return f.isDirectory(); 
     } 
    }); 

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

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