码迷,mamicode.com
首页 > 其他好文 > 详细

NIO.2: 目錄的處理

时间:2015-07-22 22:38:01      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:

檔案系統的 I/O,除了前幾篇所說明的檔案相關處理外,另一個主題就是目錄的處理 - 讀取、走訪、過濾檔案等,說明如下:

  • 取得根目錄
 1 package idv.steven.nio2.filedir;
 2 
 3 import static java.lang.System.out;
 4 import java.nio.file.FileSystems;
 5 import java.nio.file.Path;
 6 import java.util.ArrayList;
 7 
 8 public class ListRoots {
 9 
10     public static void main(String[] args) {
11         Iterable<Path> dirs = FileSystems.getDefault().getRootDirectories();
12         
13         ArrayList<Path> list = new ArrayList<Path>();
14         for(Path name : dirs) {
15             list.add(name);
16         }
17         Path[] array = new Path[list.size()];
18         list.toArray(array);
19         
20         for(Path path : array) {
21             System.out.println(path);
22         }
23         
24         //dirs.forEach(out::println); //Java 8
25     }
26 }

如上的程式,第 11 行可以取得檔案系統的根目錄,在單根檔案系統,例如 Unix/Linux,當然就只會輸出 /,在 Windows 上執行,就看作業系統裡有幾個磁碟,像是我的電腦,執行出來就會是 .....

C:\
D:\
E:\
F:\
H:\

程式 13~22 行是傳統 Java 的寫法,使用 Lambda 的話,只要第 24 行這樣一行程式就可以了。

  • 檢查檔案或目錄是否存在? 
 1 package idv.steven.nio2.filedir;
 2 
 3 import java.nio.file.FileSystems;
 4 import java.nio.file.Files;
 5 import java.nio.file.LinkOption;
 6 import java.nio.file.Path;
 7 
 8 public class CheckExist {
 9     public static void main(String[] args) {
10         Path path = FileSystems.getDefault().getPath("D:/TEST");
11         boolean isNotExist = Files.notExists(path, new LinkOption[] {LinkOption.NOFOLLOW_LINKS});
12         System.out.println(isNotExist);
13     }
14 }

不管是檢查檔案或目錄是否存在,使用的方法是一樣的,上面的程式是檢查 D:/ 下是否有 TEST 這個子目錄,注意看一下第 11 行,這裡使用的是 notExists 這個 method,Files 類別也提供有 exists method,notExists 就等於 !exists。

  • 讀取目錄
 1 package idv.steven.nio2.filedir;
 2 
 3 import java.io.IOException;
 4 import java.nio.file.DirectoryStream;
 5 import java.nio.file.Files;
 6 import java.nio.file.Path;
 7 import java.nio.file.Paths;
 8 
 9 public class ListDirectory {
10 
11     public static void main(String[] args) {
12         Path path = Paths.get("/home/steven/TEST");
13         try (DirectoryStream<Path> ds = Files.newDirectoryStream(path, "[rR]eadme*.txt")) {
14             for(Path file : ds) {
15                 System.out.println(file.getFileName());
16             }
17         }
18         catch (IOException e) {
19             System.err.println(e);
20         }
21     }
22 }

如上是 java.nio 提供的讀取目錄內容的方法之一,第二個參數不填,則會列出目錄裡的所有檔案、子目錄、連結等所有內容。第二個參數有那些選項呢? 如下:

  1. *: 比對所有字元。
  2. **: 跨目錄比對所有字元。
  3. ?: 比對一個字元,如果用這個選項,例如: a?.txt,那麼就一定是 a 後面要接一個字元,a.txt 不算在這個條件裡。
  4. { }: 比對大括號內所有 pattern,例如: {a?.txt, *.jpg},那麼可能就會列出 ab.txt、face.jpg、leg.jpg …
  5. [ ]: 比對中括號內所有列出的字元,像是上面的程式,會找出 readme*.txt 及 Readme*.txt 的檔案,中括號內,可以放入如下選項:

(1) [0-9]: 0 到 9 的所有數字,當然,也可以是[3-7],只搜尋 3 到 7 的數字。

(2) [A-Z]: 大寫 A 到 Z。

(3) [a-z,A-Z]: 大小寫的所有英文字母。

(4) [2345RT]: 比對到括號中任一字元。

6. 大括號、中括號內也可以有 *、? 等萬用字元,並複合使用,例如: {*[0-9].jpg},輸出的結果可能就會是 face1.jpg、leg3.jpg …

  •  走訪目錄

上面的說明有提到讀取目錄的方法,如果我們要走訪目錄呢? java.nio 提到了一個介面 FileVisitor,實作這個介面後,會有四個 callback method,在走訪時,java.nio 會在各個時間點呼叫這四個 method,讓我們可以進行各種處理,四個介面說明如下:

  1. preVisitDirectory: 走訪一個目錄前。
  2. postVisitDirectory: 走訪一個目錄之後。
  3. visitFile: 走訪一個檔案時。
  4. visitFileFailed: 走訪檔案失敗,通常是因為無存取權限。

接下來看一下程式:

 1 package idv.steven.nio2.filedir;
 2 
 3 import java.io.IOException;
 4 import java.nio.file.FileVisitResult;
 5 import java.nio.file.FileVisitor;
 6 import java.nio.file.Files;
 7 import java.nio.file.Path;
 8 import java.nio.file.Paths;
 9 import java.nio.file.attribute.BasicFileAttributes;
10 import static java.nio.file.FileVisitResult.*;
11 
12 public class WalkFolder implements FileVisitor<Path> {
13 
14     @Override
15     public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
16             throws IOException {
17         
18         System.out.println("preVisitDirectory: " + dir.getFileName());
19 
20         return CONTINUE;
21     }
22 
23     @Override
24     public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
25             throws IOException {
26         
27         System.out.println("visitFile: " + file.getFileName());
28         
29         return CONTINUE;
30     }
31 
32     @Override
33     public FileVisitResult visitFileFailed(Path file, IOException exc)
34             throws IOException {
35         
36         System.out.println("visitFileFailed: " + file.getFileName());
37         
38         return CONTINUE;
39     }
40 
41     @Override
42     public FileVisitResult postVisitDirectory(Path dir, IOException exc)
43             throws IOException {
44 
45         System.out.println("postVisitDirectory: " + dir.getFileName());
46         
47         return CONTINUE;
48     }
49     
50     public static void main(String[] args) throws IOException {
51         WalkFolder walkFolder = new WalkFolder();
52         
53         Files.walkFileTree(Paths.get("D:/TEST"), walkFolder);
54     }
55 }

這個程式會走訪 D:/TEST  下的所有子目錄及檔案,在 method 中可進行需要的處理,特別要提出來說明的是返回值,上面四個 method 都返回 CONTINE,表示繼續走訪,java.nio 提供了四個返回值,如下:

  1. CONTINUE: 繼續走訪
  2. SKIP_SIBLINGS: 跳過同一階層的檔案或子目錄後繼續走訪
  3. SKIP_SUBTREE: 跳過正走訪的這個目錄後繼續走訪
  4. TERMINATE: 停止走訪

在許多的情況下,我們並不會需要同時實作四個 method,所以 java.nio 提供了一個 SimpleFileVisitor 類別,繼續這個類別,我們只需要 override 要特別處理的 method,這樣會方便些。 

 

NIO.2: 目錄的處理

标签:

原文地址:http://www.cnblogs.com/stevwn/p/4662748.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!