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.FileUtilsFile 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