¿Cómo puedo iterar a través de los archivos en un directorio en Java?

Necesito obtener una lista de todos los archivos en un directorio, incluidos los archivos en todos los subdirectorios. ¿Cuál es la forma estándar de realizar la iteración de directorios con Java?

Puede usar File#isDirectory() para probar si el archivo (ruta) dado es un directorio. Si esto es true , simplemente vuelve a llamar al mismo método con su resultado File#listFiles() . Esto se llama recursividad .

Aquí hay un ejemplo básico de patada de salida.

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

Tenga en cuenta que esto es sensible a StackOverflowError cuando el árbol es más profundo de lo que la stack de la JVM puede contener. Puede usar un enfoque iterativo o recursión de cola en su lugar, pero ese es otro tema;)

Si está utilizando Java 1.7, puede usar java.nio.file.Files.walkFileTree(...) .

Por ejemplo:

 public class WalkFileTreeExample { public static void main(String[] args) { Path p = Paths.get("/usr"); FileVisitor fv = new SimpleFileVisitor() { @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 está utilizando Java 8, puede usar la interfaz de flujo con java.nio.file.Files.walk(...) :

 public class WalkFileTreeExample { public static void main(String[] args) { try (Stream paths = Files.walk(Paths.get("/usr"))) { paths.forEach(System.out::println); } catch (IOException e) { e.printStackTrace(); } } } 

Consulte la clase FileUtils en Apache Commons, específicamente iterateFiles :

Permite la iteración sobre los archivos en el directorio dado (y opcionalmente sus subdirectorios).

Para Java 7+, también hay https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html

Ejemplo tomado del Javadoc:

 List listSourceFiles(Path dir) throws IOException { List result = new ArrayList<>(); try (DirectoryStream 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; } 

Usando org.apache.commons.io.FileUtils

 File file = new File("F:/Lines"); Collection files = FileUtils.listFiles(file, null, true); for(File file2 : files){ System.out.println(file2.getName()); } 

Use falso si no desea archivos de subdirectorios.

Es un árbol, por lo que la recursividad es tu amigo: comienza con el directorio principal y llama al método para obtener una matriz de archivos secundarios. Itera a través de la matriz hija. Si el valor actual es un directorio, páselo a una llamada recursiva de tu método. De lo contrario, procese el archivo de la hoja de forma adecuada.

Como se señaló, este es un problema de recursión. En particular, es posible que desee mirar

 listFiles() 

En la API de archivos java aquí . Devuelve una matriz de todos los archivos en un directorio. Usando esto junto con

 isDirectory() 

para ver si necesita recurse más es un buen comienzo.

Para agregar con @msandiford, como la mayoría de las veces cuando se camina un árbol de archivos, es posible que desee ejecutar una función como un directorio o se visita cualquier archivo en particular. Si eres reacio a usar transmisiones Se pueden implementar los siguientes métodos anulados

 Files.walkFileTree(Paths.get(Krawl.INDEXPATH), EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor() { @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; } });