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?

136
demandé sur james.garriss 2010-07-01 05:02:54

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 ;)

178
répondu BalusC 2010-07-01 01:13:25

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();
    }
  }

}
70
répondu msandiford 2018-04-11 19:25:53

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).

27
répondu Ben J 2014-04-06 09:17:10

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;
}
7
répondu Wim Deblauwe 2015-12-16 13:09:14

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.

6
répondu fjkjava 2017-09-01 12:56:45

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.

2
répondu duffymo 2010-07-01 01:06:27

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.

2
répondu Chimmy 2017-09-01 13:03:51

à 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;
        }
});
0
répondu Raghu DV 2017-12-27 03:45:04