Изучите различные способы поиска файла в заданном каталоге и подкаталогах с помощью Java. Приведенные примеры найдут все файлы с указанными именами, если в подкаталогах есть более одного файла с одинаковым именем.
1. Найти файл, пройдя по каталогам
Самый простой и понятный способ найти все файлы в каталоге или его подкаталогах — это пройтись по всем файлам с помощью метода Files.walk(). Этот метод обходит каталоги в глубину, поэтому файлы в самых глубоких подкаталогах ищутся первыми.
Мы можем опционально передать глубину уровня подкаталога для поиска, если структура каталога слишком вложена, и мы не хотим идти так глубоко. Обратите внимание, что когда мы закрываем Stream, каталог также закрывается.
String fileNameToFind = "test.txt";File rootDirectory = new File("c:/temp");final List<File> foundFiles = new ArrayList<>();try(Stream<Path> walkStream = Files.walk(rootDirectory.toPath())) {walkStream.filter(p -> p.toFile().isFile()).forEach(f -> {if(f.toString().endsWith(fileNameToFind)) {foundFiles.add(f.toFile());}});}
Если мы хотим перебрать 5 уровней подкаталогов, то мы можем использовать следующую функцию:
try(Stream<Path> walkStream = Files.walk(rootDirectory.toPath(), 5)) {...}
Если мы хотим остановить поиск после того, как будет найден первый файл, то мы можем использовать метод Stream.findFirst() с потоком путей.
Optional<Path> foundFile;try(Stream<Path> walkStream = Files.walk(rootDirectory.toPath())) {foundFile = walkStream.filter(p -> p.toFile().isFile()).filter(p -> p.toString().endsWith(fileNameToFind)).findFirst();}if(foundFile.isPresent()) {System.out.println(foundFile.get());} else {System.out.println("File not found");}
2. Использование рекурсии
Рекурсия — это старомодный способ перебрать все файлы и подкаталоги и применить пользовательскую логику для сопоставления имен файлов. Тем не менее, мы можем использовать его, если он подходит нашему решению.
Следующий метод findFilesByName() рекурсивно перебирает файлы и подкаталоги и добавляет соответствующие файлы в foundFilesList.
Рекурсивная функция сначала перечисляет все файлы с помощью метода File.listFiles(), а затем выполняет итерацию по ним. Во время итерации она далее вызывает listFiles() для всех дочерних каталогов, которые она проверяет с помощью метода file.isDirectory().
После завершения рекурсии мы можем проверить файлы, найденные в этом списке.
final List<File> foundFilesList = new ArrayList<>();findFilesByName(rootDirectory, fileNameToFind, foundFilesList);public static void findFilesByName(File rootDir, String filenameToSearch, List<File> foundFilesList) {Collection<File> files = List.of(rootDir.listFiles());for(Iterator iterator = files.iterator(); iterator.hasNext(); ) {File file =(File) iterator.next();if(file.isDirectory()) {findFilesByName(file, filenameToSearch, foundFilesList);} else if(file.getName().equalsIgnoreCase(filenameToSearch)){foundFilesList.add(file);}}}System.out.println(foundFilesList); //Prints the found files
3. Заключение
Этот короткий урок Java научил нас находить файл по имени в заданном каталоге и его подкаталогах. Мы также научились контролировать поиск вплоть до заданной глубины подкаталогов. Мы также использовали метод сокращения потока findFirst(), если хотели прекратить поиск после первого появления соответствующего файла.