Мне нужно получить список всех файлов в каталоге, включая файлы во всех подкаталогах. Каков стандартный способ выполнения итерации каталогов с Java?
175
Вы можете использовать, File#isDirectory()
чтобы проверить, является ли данный файл (путь) каталогом. Если это так true
, то вы просто снова вызываете тот же метод с его File#listFiles()
результатом. Это называется рекурсия .
Вот основной пример начала.
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());
}
}
}
Обратите внимание, что это чувствительно к тому, StackOverflowError
когда дерево глубже, чем может вместить стек JVM. Вы можете вместо этого использовать итеративный подход или хвостовую рекурсию , но это уже другая тема;)
NullPointerException
когда файловая система меняется между вызовамиisDirectory
и,listFiles
как это может случиться, еслиSystem.out.println
блоки или вам просто не повезло. Проверка того, что выводlistFiles
не равен нулю, решит это условие гонки.java.nio.file.DirectoryStream
вы можете перебирать каталог, и его можно было бы реализовать, чтобы иметь небольшой объем памяти, но единственный способ точно сказать это контролировать использование памяти на конкретной платформе.Если вы используете Java 1.7, вы можете использовать
java.nio.file.Files.walkFileTree(...)
.Например:
Если вы используете Java 8, вы можете использовать потоковый интерфейс с
java.nio.file.Files.walk(...)
:источник
Проверьте класс FileUtils в Apache Commons - в частности, iterateFiles :
источник
Для Java 7+ есть также https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html
Пример взят из Javadoc:
источник
С помощью
org.apache.commons.io.FileUtils
Используйте false, если вы не хотите файлы из подкаталогов.
источник
Это дерево, поэтому рекурсия - ваш друг: начните с родительского каталога и вызовите метод, чтобы получить массив дочерних файлов. Итерация по дочернему массиву. Если текущее значение является каталогом, передайте его рекурсивному вызову вашего метода. Если нет, обработайте файл листа соответствующим образом.
источник
Как уже отмечалось, это проблема рекурсии. В частности, вы можете посмотреть на
В Java File API здесь . Возвращает массив всех файлов в каталоге. Используя это вместе с
посмотреть, нужно ли вам продолжать курс, - это хорошее начало.
источник
Чтобы добавить ответ @msandiford, так как в большинстве случаев при обходе дерева файлов вам может потребоваться выполнить функцию как каталог или посещение любого конкретного файла. Если вы не хотите использовать потоки. Следующие методы могут быть переопределены
источник
Вы также можете неправильно использовать File.list (FilenameFilter) (и варианты) для обхода файла. Короткий код и работает в ранних версиях Java, например:
источник