如何遍历Java中的目录中的文件?
我需要获取目录中所有文件的列表,包括所有子目录中的文件。 用Java完成目录迭代的标准方法是什么?
您可以使用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()); } } }
请注意,当树比JVM的堆栈更深时,这对StackOverflowError
非常敏感。 您可能想要使用迭代方法或尾递归 ,但这是另一个主题;)
如果您正在使用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(); } } }
查看Apache Commons中的FileUtils类 – 特别是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 File API。 它返回一个目录中所有文件的数组。 与此一起使用
isDirectory()
看看你是否需要进一步缓解是一个好的开始。