Как я могу перебирать файлы в каталоге на Java?



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

244   8  

8 ответов:

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

если вы используете 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();
    }
  }

}

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

позволяет итерации по файлам в данном каталоге (и, возможно, его подкаталоги).

для 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;
}

используя 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, если вы не хотите файлы из подкаталогов.

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

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

listFiles() 

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

isDirectory()

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

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

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;
        }
});

Comments

    Ничего не найдено.