Trong bài viết trước, chúng ta đã cùng nhau tìm hiểu cách liệt kê các tập tin, thư mục trong một thư mục nào đó nhưng chỉ cho thư mục mà chúng ta muốn mà thôi. Nếu các bạn muốn liệt kê luôn tất cả các thư mục con trong thư mục này nữa, vì một thư mục có thể chứa nhiều thư mục con và trong các thư mục con đó cũng có thể chứa nhiều thư mục con khác nữa, các bạn có thể sử dụng phương thức static walk() của class Files để làm điều này.
Phương thức walk() này có 2 phương thức overloading:
1 |
walk(Path start,int maxDepth, FileVisitOption... options) |
và:
1 |
walk(Path start, FileVisitOption... options) |
Đối với phương thức walk(Path start, int maxDepth, FileVisitOption… options) thì tham số đầu tiên là thư mục mà các bạn cần liệt kê.
Tham số thứ 2 liên quan đến mức độ các bạn muốn liệt kê. Ví dụ như thư mục của bạn có chứa thư mục con, thư mục con này có chứa thư mục con khác, thư mục con khác cũng có chứa những thư mục con khác nữa, … Mức độ các bạn muốn liệt kê mức độ là bao nhiêu thì hễ khai báo cho tham số thứ 2 này, bắt đầu từ 1 các bạn nhé! 0 thì chính là thư mục các bạn truyền vào, còn âm thì sẽ báo lỗi.
Tham số thứ 3 liên quan đến việc các option chúng ta muốn làm đối với các tập tin thư mục khi chúng ta liệt kê. Hiện tại thì Java cho phép chúng ta có liệt kê các thư mục symbolic link hay không:
1 |
FileVisitOption.FOLLOW_LINKS |
Mặc định nếu chúng ta không khai báo tham số này thì là không liệt kê symbolic link các bạn nhé!
Phương thức walk(Path start, FileVisitOption… options) thì các tham số cũng như mình nói ở trên. Chỉ có điều là, tham số maxDepth sẽ mặc định có giá trị là Integer.MAX_VALUE (tương đương với 2^31-1), đồng nghĩa với việc nó sẽ liệt kê hết tất cả các thư mục, tập tin.
Ví dụ, mình muốn liệt kê các tập tin, thư mục con của thư mục với mức độ là 2, mình có thể viết code như sau:
1 2 3 4 5 |
String folder = "/Users/khanh/Documents/code/huongdanjava.com"; Path folderPath = Paths.get(folder); Files.walk(folderPath, 2) .forEach(path -> System.out.println(path.toFile().getName())); |
Khi chạy code ví dụ này, các bạn sẽ thấy kết quả như sau:
Như các bạn thấy, thư mục mule-esb-dynamic-property và tất cả các tập tin thư mục, tập tin trong thư mục đã được liệt kê.
Nếu các bạn muốn thêm một số thao tác nào đó cho một số tập tin hoặc thư mục khi liệt kê thì các bạn có thể sử dụng phương thức static walkFileTree() cũng của class Files.
Phương thức này cũng có 2 phương thức overloading là:
1 |
walkFileTree(Path start, Set<FileVisitOption> options, int maxDepth, FileVisitor<? super Path> visitor) |
và:
1 |
walkFileTree(Path start, FileVisitor<? super Path> visitor) |
Tham số start, options và maxDepth thì mình đã nói ở trên rồi các bạn nhé. Ở đây, chúng ta có thêm một tham số tên là visitor của interface FileVisitor giúp chúng ta thêm các thao tác cho các tập tin, trước và sau khi liệt kê một thư mục mà chúng ta muốn.
Nội dung của interface FileVisitor này như sau:
1 2 3 4 5 6 7 8 9 10 |
public interface FileVisitor<T> { FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs) throws IOException; FileVisitResult visitFile(T file, BasicFileAttributes attrs) throws IOException; FileVisitResult visitFileFailed(T file, IOException exc) throws IOException; FileVisitResult postVisitDirectory(T dir, IOException exc) throws IOException; } |
Implementation của interface FileVisitor là class SimpleFileVisitor các bạn nhé! Hãy override lại những abstract method này theo nhu cầu của mình!
Ví dụ, mình chỉ muốn in ra tất cả các thư mục có trong thư mục ví dụ, mình sẽ viết code như sau:
1 2 3 4 5 6 7 8 9 10 11 |
String folder = "/Users/khanh/Documents/code/huongdanjava.com"; Path folderPath = Paths.get(folder); Files.walkFileTree(folderPath, Collections.emptySet(), 2, new SimpleFileVisitor<>() { @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { System.out.println(dir.getFileName().toString()); return FileVisitResult.CONTINUE; } }); |
Kết quả:
Enum FileVisitResult giúp chúng ta có thể điều chỉnh việc có tiếp tục liệt kê hay không hay dừng lại. Tuỳ nhu cầu, các bạn hãy sử dụng cho đúng nhé!