Avant de déboguer la fonction récursive tardive de l'heure tardive: y a-t-il une commande pour obtenir des sous-résidents? GivemesubDirs (Downtopath) CODE>?
// 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;
}
8 Réponses :
Non, il n'y a pas de fonctionnalité de ce type dans l'API standard Java. Mais il y a dans
Vous pouvez obtenir tous les sous-didifiers avec le snippet suivant:
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; }
@Hh arranges.Aslist code> renvoie apparemment une liste immuable. Nous devons donc construire une nouvelle arraylist
mutable code> en plus de celui-ci.
Pourquoi avez-vous utilisé la liste
Pas de raison particulière. Cependant, je ne pouvais pas utiliser arranges.aslist code> - il n'y a pas d'équivalent pour
hashset code>.
Liste CODE> Effectuez plus vite ici, je crois aussi.
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); }
Quelque chose ne va pas avec la compilation: Stackoverflow.com/Questtions/2581158/...
Une autre version sans récursion et ordre alphabétique. Utilise également un ensemble pour éviter les boucles (un problème dans les systèmes UNIX avec des liens).
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; }
Vous ne devriez en fait pas utiliser la classe Java.Util.stack, car elle est cassée. Utilisez ARRAYDEQUET à la place: DEQUE
@Chris: Il utilise la synchronisation par méthode sur la pop, la poussée (basée sur le vecteur, qui aime également ce type de synchronisation). C'est une performance inutile touchée si vous n'êtes pas multi-threading ce code et de nombreux scénarios multi-threading où vous avez besoin d'un grain de synchronisation plus grand. (J'ai regardé après le commentaire de l'assistant, comme j'avais la même question)
Le code exemple ci-dessus est manquant ");" à la fin de la déclaration. Le code correct doit être:
File file = new File("path"); File[] subdirs = file.listFiles(new FileFilter() { public boolean accept(File f) { return f.isDirectory(); } });
Utilisation de la récursion:
private void getAllSubFoldersInPath(File path) { File[] files=path.listFiles(); try { for(File file: files) { if(file.isDirectory()) { System.out.println("DIRECTORY:"+file.getCanonicalPath()); getAllSubFoldersInPath(file); } else { System.out.println("FILE: "+file.getCanonicalPath()); } } } catch (Exception e) { e.printStackTrace(); } }
Ceci est un code amélioré avec une approche Java 8. Ce code fonctionnera sur une base de récursion et trouvera les répertoires jusqu'à la dernière racine.
List<File> subdirs = Arrays.asList(file.listFiles(File::isDirectory));
Tout ce qui a mis dans une certaine magie de Lambda: p> juste commencer par le fichier root (qui devrait être un répertoire) et une liste vide. P>
C'est une bonne pratique pour expliquer la réponse avec la solution à Stackoverflow.
Imo il vaut mieux aller de haut en bas puis ascendant (comme dans ma solution ci-dessous :)). Il est plus naturel de cette façon et vous n'avez pas à stocker les chemins sur des niveaux intermédiaires.
Qu'essayez-vous de faire? Essayez-vous de répertorier tous les sous-répertoires jusqu'à ce que vous atteigniez un certain niveau?
Dans le titre dit: "récursivement" mais dans votre code n'est pas récursif? Vous recherchez une solution récursive ou pour une solution non récursive? Quel est le nom complet de
fileObject code> est que
javax.tools.fileObject code>
@Ocar: Récursion de bas-haut. Pas Javax. *. S'il vous plaît, lisez l'avertissement, c'est incomplet.