Как мне перебрать файлы в каталоге на Java? - PullRequest
151 голосов
/ 01 июля 2010

Мне нужно получить список всех файлов в каталоге, включая файлы во всех подкаталогах. Каков стандартный способ выполнения итерации каталогов с Java?

Ответы [ 9 ]

191 голосов
/ 01 июля 2010

Вы можете использовать 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. Возможно, вы захотите использовать итеративный подход или хвостовую рекурсию , но это уже другая тема;)

77 голосов
/ 01 июля 2010

Если вы используете Java 1.7, вы можете использовать java.nio.file.Files.walkFileTree(...).

Например:

public class WalkFileTreeExample {

  public static void main(String[] args) {
    Path p = Paths.get("/usr");
    FileVisitor<Path> fv = new SimpleFileVisitor<Path>() {
      @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();
    }
  }

}

Если вы используете Java 8, вы можетеиспользуйте интерфейс потока с java.nio.file.Files.walk(...):

public class WalkFileTreeExample {

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

}
27 голосов
/ 01 июля 2010

Проверьте класс FileUtils в Apache Commons - в частности, iterateFiles :

Позволяет выполнять итерации по файлам в данном каталоге (и, необязательно, его подкаталогах).

7 голосов
/ 16 декабря 2015

Для Java 7+ есть также https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html

Пример взят из Javadoc:

List<Path> listSourceFiles(Path dir) throws IOException {
   List<Path> result = new ArrayList<>();
   try (DirectoryStream<Path> 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;
}
7 голосов
/ 07 ноября 2014

Использование org.apache.commons.io.FileUtils

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

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

3 голосов
/ 01 июля 2010

Это дерево, поэтому рекурсия - ваш друг: начните с родительского каталога и вызовите метод, чтобы получить массив дочерних файлов. Итерация по дочернему массиву. Если текущее значение является каталогом, передайте его рекурсивному вызову вашего метода. Если нет, обработайте файл листа соответствующим образом.

2 голосов
/ 01 июля 2010

Как уже отмечалось, это проблема рекурсии. В частности, вы можете посмотреть на

listFiles() 

В API Java File здесь . Возвращает массив всех файлов в каталоге. Используя это вместе с

isDirectory()

чтобы узнать, нужно ли вам продолжать курс, это хорошее начало.

0 голосов
/ 29 июня 2019

Вы также можете неправильно использовать File.list (FilenameFilter) (и варианты) для обхода файла. Короткий код и работает в ранних версиях Java, например:

// list files in dir
new File(dir).list(new FilenameFilter() {
    public boolean accept(File dir, String name) {
        String file = dir.getAbsolutePath() + File.separator + name;
        System.out.println(file);
        return false;
    }
});
0 голосов
/ 27 декабря 2017

Для добавления с ответом @msandiford, так как в большинстве случаев при обходе дерева файлов вам может потребоваться выполнить функцию как каталог или посещение любого конкретного файла. Если вы не хотите использовать потоки. Следующие переопределенные методы могут быть реализованы

Files.walkFileTree(Paths.get(Krawl.INDEXPATH), EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
    new SimpleFileVisitor<Path>() {
        @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;
        }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...