天天看點

java 遞歸擷取目錄下所有檔案

對于一個嵌套的目錄,擷取目錄下所有的檔案,可以使用一下兩種方式:

1、遞歸方法:

static List<String> ergodic(File file, List<String> resultFileName) {
    File[] files = file.listFiles();
    if (files == null)
      return resultFileName;// 判斷目錄下是不是空的
    for (File f : files) {
      if (f.isDirectory()) {// 判斷是否檔案夾
        //resultFileName.add(f.getPath());
        ergodic(f, resultFileName);// 調用自身,查找子目錄
      } else
        resultFileName.add(f.getPath());
    }
    return resultFileName;
}      

File類提供了如下兩個方法:

  • file.list():傳回目錄下檔案和子目錄名;(不會遞歸)
  • file.listFiles():傳回目錄下檔案和子目錄File對象;(不會遞歸)

2、Files.walk():

在jdk8中,可以使用walk方法遞歸的去查找目錄下所有檔案,例如:

static void walk(String path) throws Exception {
    try (Stream<Path> paths = Files.walk(Paths.get(path))) {
      paths
        .filter(Files::isRegularFile)
        .forEach(System.out::println);
    } 
}      

說明:

  • 上例使用了Try with Resources模式,它可以確定無論在什麼情況下,流都将關閉。
  • walk方法會自動遞歸子目錄;

Files.walk通過遞歸周遊以給定起始檔案為根的檔案樹來傳回由Path延遲填充的流。 檔案樹是深度優先周遊的,有兩種重載的Files.walk方法:

  • maxDepth參數,設定要遞歸的深度;Files.walk(Paths.get(path),2)
  • 預設不會自動跟随符号連結, 設定options參數FOLLOW_LINKS選項,則遵循符号連結。 Files.walk(Paths.get(path),FileVisitOption.FOLLOW_LINKS)

接下來看一些示例:

var dirName = "C:/Users/Jano/Downloads";

//過濾出目錄
try (Stream<Path> paths = Files.walk(Paths.get(dirName))) {
    paths.filter(Files::isDirectory)
            .forEach(System.out::println);
}

//按字尾名過濾
try (Stream<Path> paths = Files.walk(Paths.get(dirName), 2)) {
    paths.map(path -> path.toString()).filter(f -> f.endsWith(".pdf"))
            .forEach(System.out::println);
}