Comment puis-je itérer les fichiers dans un répertoire en Java?
je dois obtenir une liste de tous les fichiers d'un répertoire, y compris les fichiers de tous les sous-répertoires. Quelle est la méthode standard pour effectuer L'itération des répertoires avec Java?
8 réponses
vous pouvez utiliser File#isDirectory()
pour tester si le fichier (chemin) donné est un répertoire. Si c'est true
, alors vous appelez juste la même méthode à nouveau avec son File#listFiles()
résultat. C'est ce qu'on appelle récursion .
voici un exemple de coup d'envoi.
public static void main(String... args) {
File[] files = new File("C:/").listFiles();
showFiles(files);
}
public static void showFiles(File[] files) {
for (File file : files) {
if (file.isDirectory()) {
System.out.println("Directory: " + file.getName());
showFiles(file.listFiles()); // Calls same method again.
} else {
System.out.println("File: " + file.getName());
}
}
}
notez que ceci est sensible à StackOverflowError
lorsque l'arbre est plus profond que la pile du JVM peut tenir. Vous souhaiterez peut-être utiliser une approche itérative ou tail-recursion à la place, mais c'est un autre sujet ;)
si vous utilisez Java 1.7, vous pouvez utiliser java.nio.file.Files.walkFileTree(...)
.
par exemple:
public class WalkFileTreeExample {
public static void main(String[] args) {
Path p = Paths.get("/usr");
FileVisitor<Path> fv = new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
System.out.println(file);
return FileVisitResult.CONTINUE;
}
};
try {
Files.walkFileTree(p, fv);
} catch (IOException e) {
e.printStackTrace();
}
}
}
si vous utilisez Java 8, Vous pouvez utiliser l'interface stream avec java.nio.file.Files.walk(...)
:
public class WalkFileTreeExample {
public static void main(String[] args) {
try (Stream<Path> paths = Files.walk(Paths.get("/usr"))) {
paths.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
regardez la classe FileUtils dans Apache Commons-spécifiquement iterateFiles :
Permet d'itération sur les fichiers d'un répertoire donné (et éventuellement ses sous-répertoires).
pour Java 7+, Il y a aussi https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html
exemple tiré du Javadoc:
List<Path> listSourceFiles(Path dir) throws IOException {
List<Path> result = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{c,h,cpp,hpp,java}")) {
for (Path entry: stream) {
result.add(entry);
}
} catch (DirectoryIteratorException ex) {
// I/O error encounted during the iteration, the cause is an IOException
throw ex.getCause();
}
return result;
}
utilisant org.apache.commons.io.FileUtils
File file = new File("F:/Lines");
Collection<File> files = FileUtils.listFiles(file, null, true);
for(File file2 : files){
System.out.println(file2.getName());
}
utilisez false si vous ne voulez pas de fichiers de sous répertoires.
c'est un arbre, donc la récursion est votre ami: commencez avec le répertoire parent et appelez la méthode pour obtenir un tableau de fichiers enfants. Parcourir le tableau enfant. Si la valeur actuelle est un répertoire, le passer à un appel récursif de votre méthode. Si ce n'est pas le cas, traiter le fichier leaf de façon appropriée.
comme indiqué, il s'agit d'un problème de récursion. En particulier, vous pouvez regarder à
listFiles()
dans L'API de fichier java ici . Elle retourne un tableau de tous les fichiers dans un répertoire. En utilisant ceci avec
isDirectory()
pour voir si vous devez répéter encore est un bon début.
à ajouter avec la réponse @msandiford, comme la plupart des fois où un arbre de fichiers est walked u peut vouloir exécuter une fonction comme un répertoire ou un fichier particulier est visité. Si u est réticent à utiliser les flux. Les méthodes suivantes peuvent être appliquées
Files.walkFileTree(Paths.get(Krawl.INDEXPATH), EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
// Do someting before directory visit
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
// Do something when a file is visited
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc)
throws IOException {
// Do Something after directory visit
return FileVisitResult.CONTINUE;
}
});