Рубрики
Без рубрики

Список файлов в каталоге на Java

Изучите несколько различных способов перечисления файлов в каталоге и подкаталогах на Java.

Автор оригинала: baeldung.

1. Обзор

1. Обзор

1. Обзор

1. Обзор

public Set listFilesUsingJavaIO(String dir) {
    return Stream.of(new File(dir).listFiles())
      .filter(file -> !file.isDirectory())
      .map(File::getName)
      .collect(Collectors.toSet());
}

1. Обзор

Однако Java 7 представила более быструю альтернативу к Файл#listFiles называемый DirectoryStream .

Давайте посмотрим, как выглядит эквивалент:

public Set listFilesUsingDirectoryStream(String dir) throws IOException {
    Set fileList = new HashSet<>();
    try (DirectoryStream stream = Files.newDirectoryStream(Paths.get(dir))) {
        for (Path path : stream) {
            if (!Files.isDirectory(path)) {
                fileList.add(path.getFileName()
                    .toString());
            }
        }
    }
    return fileList;
}

Мы легко видим, что хотя DirectoryStream может быть быстрее, он не является частью Stream API и не совсем так поддается работе с ним.

Кроме того, DirectoryStream требует, чтобы мы закрыли ресурс , то есть обернули его с помощью try-with-resources , to.

4. Листинг в Java 8

Если мы используем Java 8, мы можем извлечь выгоду из нового java.nio.file.Files#list метод.

Он возвращает лениво заполненный Поток записей в каталоге.

Давайте рассмотрим простой пример:

public Set listFilesUsingFilesList(String dir) throws IOException {
    try (Stream stream = Files.list(Paths.get(dir))) {
        return stream
          .filter(file -> !Files.isDirectory(file))
          .map(Path::getFileName)
          .map(Path::toString)
          .collect(Collectors.toSet());
    }
}

Если нам требуется своевременная утилизация ресурсов файловой системы, то мы должны использовать оператор try-with-resources . Таким образом, мы удостоверяемся, что поток будет закрыт сразу после завершения операций потока.

5. Ходьба

Или мы можем перечислить все файлы в каталоге, пройдя по нему до настроенной глубины .

Давайте воспользуемся java.nio.file.Files#walk чтобы перечислить все файлы в каталоге на заданную глубину:

public Set listFilesUsingFileWalk(String dir, int depth) throws IOException {
    try (Stream stream = Files.walk(Paths.get(dir), depth)) {
        return stream
          .filter(file -> !Files.isDirectory(file))
          .map(Path::getFileName)
          .map(Path::toString)
          .collect(Collectors.toSet());
    }
}

Конечно, не забудьте использовать try-with-resources , чтобы дескриптор файла для dir был закрыт правильно.

Или, если мы хотим иметь больше контроля над тем, что происходит с каждым посещенным файлом, мы также можем предоставить реализацию посетителя:

public Set listFilesUsingFileWalkAndVisitor(String dir) throws IOException {
    Set fileList = new HashSet<>();
    Files.walkFileTree(Paths.get(dir), new SimpleFileVisitor() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
          throws IOException {
            if (!Files.isDirectory(file)) {
                fileList.add(file.getFileName().toString());
            }
            return FileVisitResult.CONTINUE;
        }
    });
    return fileList;
}

Это удобно, когда мы хотим сделать дополнительное чтение, перемещение или удаление файлов по ходу работы.

6. Заключение

В этом кратком руководстве мы рассмотрели различные способы перечисления файлов в каталоге.

Как всегда, полный исходный код примеров доступен на GitHub .