walkFileTree、FileVisitor遍歷檔案/目錄
[瘋狂Java]NIO.2:walkFileTree、FileVisitor(遍歷檔案/目錄)
2016年05月16日 14:10:48 Lirx_Tech 閱讀數:10389 標籤: 瘋狂Java NIO.2 walkFileTree FileVisitor 更多
個人分類: 瘋狂Java筆記
1. 遍歷檔案和目錄——FileVisitor:
1) 在舊版本中遍歷檔案系統只能通過遞迴的方法來實現,但是這種方法不僅消耗資源大而且效率低;
2) NIO.2的Files工具類提供了一個靜態工具方法walkFileTree來高效並優雅地遍歷檔案系統;
3) walkFileTree:
i. 原型:static Path Files.walkFileTree(Path start, FileVisitor<? super Path> visitor);
ii. 表示從start代表的節點開始遍歷檔案系統;
iii. 其中visitor是遍歷過程中的行為控制器;
4) 遍歷行為控制器——FileVisitor:
i. 它是一個介面,裡面定義了4個方法用來指定當你訪問一個節點之前、之中、之後、失敗時應該採取什麼行動;
ii. 這個設計非常優雅和科學,畢竟你在遍歷檔案系統時想要做的事情無外乎發生在這幾個時間點上,Java全部為你考慮好了,並搭好了框架!多麼的貼心!!
iii. API:
-
public interface FileVisitor<T> {
-
FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs) // 訪問一個目錄前要幹啥
-
throws IOException;
-
FileVisitResult postVisitDirectory(T dir, IOException exc) // 訪問一個目錄後要幹啥
-
throws IOException;
-
FileVisitResult visitFile(T file, BasicFileAttributes attrs) // 正在訪問一個檔案時要幹啥
-
throws IOException;
-
FileVisitResult visitFileFailed(T file, IOException exc) // 訪問一個檔案失敗時要幹啥
-
throws IOException;
-
}
!!注意,裡面的檔案和目錄要區別開;
!可以看到它是一個模板介面,但是在walkFileTree中它的型別已經確定了就是Path,因此裡面的T型別就是Path型別了;
iv. 介面方法的返回值FileVisitResult是一個列舉型別,walkFileTree就是會根據這個返回值決定是否要繼續遍歷下去,如果要繼續遍歷則應該怎樣遍歷,它總共有4個列舉值:都是FileVisitResult中定義的列舉值
CONTINUE:繼續遍歷
SKIP_SIBLINGS:繼續遍歷,但忽略當前節點的所有兄弟節點直接返回上一層繼續遍歷
SKIP_SUBTREE:繼續遍歷,但是忽略子目錄,但是子檔案還是會訪問;
TERMINATE:終止遍歷
5) 實際使用中通常直接繼承FileVisitor的介面卡SimpleFileVisitor,因為只需要實現你感興趣的方法即可,無需4個方法全部都實現;
6) 示例:
-
public class Test {
-
public static void main(String[] args) throws IOException {
-
Files.walkFileTree(Paths.get(".."), new SimpleFileVisitor<Path>() {
-
@Override
-
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
-
// TODO Auto-generated method stub
-
// return super.preVisitDirectory(dir, attrs);
-
System.out.println("正在訪問:" + dir + "目錄");
-
return FileVisitResult.CONTINUE;
-
}
-
@Override
-
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
-
// TODO Auto-generated method stub
-
// return super.visitFile(file, attrs);
-
System.out.println("\t正在訪問" + file + "檔案");
-
if (file.endsWith("Test.java")) {
-
System.out.println("******找到目標檔案Test.java******");
-
return FileVisitResult.TERMINATE; // 找到了就終止
-
}
-
return FileVisitResult.CONTINUE; // 沒找到繼續找
-
}
-
});
-
}
-
}
!!Path可以像String那樣進行字串校驗,校驗路徑中的字串:都是Path的物件方法
a. boolean startsWith(String other); // 字首檢查
b. boolean startsWith(Path other);
c. boolean endsWith(String other); // 字尾檢查
d. boolean endsWith(Path other);
!!比較的都是其path成員字串裡的內容,並不會深入檔案系統用完整的絕對路徑來比較