Обход файлов и подпапок в Java: итерация и обработка файлов
Быстрый ответ
Для рекурсивного обхода директорий в Java необходимо воспользоваться методом Files.walk
. Вот пример его применения:
try (Stream<Path> files = Files.walk(Path.of("dir"))) {
files.forEach(System.out::println);
}
Этот код создаёт поток путей, выводя информацию об каждом файле и директории, начиная с "dir"
.
Обход символических ссылок с Files.walk
Применяя Files.walk
, следует учесть циклические символические ссылки, способные вызвать бесконечную рекурсию. Для предотвращения этой проблемы можно использовать опцию FileVisitOption.FOLLOW_LINKS
и установить параметр maxDepth:
Files.walk(Path.of("dir"), maxDepth, FileVisitOption.FOLLOW_LINKS);
Пользовательский обход директорий с Files.walkFileTree
Если требуется большая гибкость и контроль над процессом, стоит использовать Files.walkFileTree
с расширением FileVisitor
:
Files.walkFileTree(Path.of("dir"), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
System.out.println(file); // Привет, файл!
return FileVisitResult.CONTINUE;
}
// Переопределите другие методы для расширения возможностей
});
Этот метод дает возможность реализовать сложную логику обхода, предоставляя инструменты для действий при каждом обнаружении файла.
Использование Apache Commons IO
Если хочется абстрагироваться от низкоуровневых операций, применение Apache Commons IO и функции FileUtils.listFiles
может быть оптимальной стратегией:
Collection<File> files = FileUtils.listFiles(
new File("dir"),
TrueFileFilter.INSTANCE,
DirectoryFileFilter.DIRECTORY
);
files.forEach(System.out::println); // Вот это печать!
Библиотека Apache Commons IO предлагает простой и надежный способ для обхода, избавляя от рутины написания кода.
Фильтрация файлов с Files.newDirectoryStream
С Java 7 и посредством Files.newDirectoryStream
есть возможность одновременно обходить директории и фильтровать файлы:
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.java")) {
for (Path entry : stream) {
System.out.println(entry); // Разыскивается файл!
}
} catch (IOException | DirectoryIteratorException ex) {
// Обработка исключения
}
Этот метод органично сочетает использование DirectoryStream
с фильтрацией файлов по их расширению.
Обработка исключений в DirectoryStream
Неожиданные DirectoryIteratorExceptions
могут возникнуть во время обхода. Важно оставаться спокойным и обрабатывать исключения грамотно:
try (Stream<Path> stream = Files.walk(Path.of("dir"))) {
stream.forEach(p -> {
try {
System.out.println(p); // О, привет, файл!
} catch (Exception e) {
throw new DirectoryIteratorException(new IOException(e));
}
});
} catch (DirectoryIteratorException ex) {
// Мы готовы к этому раскладу
}
Правильная обработка исключений помогает поддерживать чистоту кода и следует best practices в области управления ошибками.
Отдаем предпочтение Path перед File
В Java 8 рекомендуется использовать Path
, замещая им File
при работе с директориями:
Path start = Paths.get("dir");
Files.walk(start)
.filter(Files::isRegularFile)
.forEach(System.out::println);
Данный подход обеспечивает актуальность кода и соответствие современным рекомендациям Java для операций чтения-записи.
Агрегирование результатов
Порой необходимо собрать все пути во время обхода. Это можно сделать следующим образом:
List<Path> gatheredPaths = Files.walk(Path.of("dir"))
.collect(Collectors.toList());
Наличие в вашем распоряжении List<Path>
позволяет осуществлять дополнительные операции, такие как сортировка или фильтрация.
Полезные материалы
- Files (Java Platform SE 8) — Официальная документация Java на тему метода
Files.walk()
. - Path (Java Platform SE 8) — Обширная информация об интерфейсе
Path
. - How to read all files in a folder from Java? – Stack Overflow — Практичный обсуждение на StackOverflow с примерами кода.
- FileVisitor (Java Platform SE 8) — Руководство по использованию интерфейса
FileVisitor
. - DirectoryWalker (Apache Commons IO 2.7 API) — Детали работы с
DirectoryWalker
в Apache Commons IO. - File I/O (Featuring NIO.2) (The Java™ Tutorials > Essential Java Classes > Basic I/O) — Официальное руководство Oracle по работе с файлами.