Java: Tạo và đọc thư mục

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực

Trong một số phương thức đã trình bày ở những bài viết trước, chẳng hạn như phương thức delete(), nó làm việc trên các tập tin, liên kết  thư mục. Nhưng làm thế nào để bạn liệt kê tất cả các thư mục ở trên cùng của một hệ thống tập tin? Làm thế nào để bạn xem nội dung của một thư mục hoặc tạo một thư mục?

Bài viết này bao gồm các trình bày cụ thể sau đây cho thư mục:

  • Liệt kê thư mục gốc của một hệ thống tập tin
  • Tạo một thư mục
  • Tạo một thư mục tạm thời
  • Liệt kê các nội dung của thư mục
  • Lọc danh sách thư mục bằng cách sử dụng globbing
  • Ghi bộ lọc thư mục riêng của bạn

Liệt kê thư mục gốc của một hệ thống tập tin

Bạn có thể liệt kê tất cả các thư mục gốc cho một hệ thống tập tin bằng cách sử dụng phương thức FileSystem.getRootDirectories. Phương thức này trả về một Iterable, cho phép bạn sử dụng vòng lặp for cải tiến để lặp qua tất cả các thư mục gốc.

Đoạn mã sau in ra các thư mục gốc cho các hệ thống tập tin mặc định:

Iterable<Path> dirs = FileSystems.getDefault().getRootDirectories();
for (Path name: dirs) {
    System.err.println(name);
}

Tạo một thư mục

Bạn có thể tạo một thư mục mới bằng cách sử dụng phương thức createDirectory(Path, FileAttribute <?>). Nếu bạn không chỉ định thuộc tính FileAttributes nào, thì thư mục mới sẽ có các thuộc tính mặc định. Ví dụ:

Path dir = ...;
Files.createDirectory(path);

Đoạn mã sau tạo một thư mục mới trên một hệ thống tập tin POSIX có quyền truy cập cụ thể:

Set<PosixFilePermission> perms =
    PosixFilePermissions.fromString("rwxr-x---");
FileAttribute<Set<PosixFilePermission>> attr =
    PosixFilePermissions.asFileAttribute(perms);
Files.createDirectory(file, attr);

Để tạo một thư mục nhiều cấp độ khi một hoặc nhiều thư mục cha có thể chưa tồn tại, bạn có thể sử dụng phương thức createDirectories(Path, FileAttribute <?>). Như với phương thức createDirectory(Path, FileAttribute <?>), bạn có thể chỉ định một bộ tùy chọn các thuộc tính tập tin ban đầu. Đoạn mã sau đây sử dụng các thuộc tính mặc định:

Files.createDirectories(Paths.get("foo/bar/test"));

Các thư mục được tạo ra theo ý muốn, từ trên xuống dưới, trong ví dụ trên sẽ là foo/bar/test, nếu thư mục foo thư mục không tồn tại thì nó được tạo ra. Tiếp theo, thư mục bar được tạo ra, và, cuối cùng, thư mục test được tạo ra.

Có thể phương thức trên sẽ không thực hiện được sau khi tạo một số, nhưng không phải tất cả các thư mục mẹ.

Tạo thư mục tạm thời

Bạn có thể tạo một thư mục tạm thời sử dụng một trong các phương thức createTempDirectory:

  • createTempDirectory(Path, String, FileAttribute <?> ...)
  • createTempDirectory(String, FileAttribute <?> ...)

Phương thức đầu tiên cho phép mã lệnh xác định vị trí cho thư mục tạm thời và phương thức thứ hai tạo ra một thư mục mới trong thư mục tạm thời mặc định.

Liệt kê các nội dung của thư mục

Bạn có thể liệt kê tất cả các nội dung của một thư mục bằng cách sử dụng phương thức newDirectoryStream(Path). Phương thức này trả về một đối tượng để thực thi giao diện DirectoryStream giao diện. Lớp thực thi giao diện DirectoryStream cũng thực hiện Iterable, vì vậy bạn có thể lặp qua luồng thư mục để đọc tất cả các đối tượng. Cách tiếp cận này phù hợp với quy mô thư mục rất lớn.


Hãy nhớ rằng:  Giá trị trả về của DirectoryStream là một luồng. Nếu bạn không sử dụng try-with-resources, thì bạn nhớ đóng luồng trong khối finally. Các try-with-resources thực hiện điều này cho bạn.

Đoạn mã sau đây cho thấy cách in nội dung của một thư mục:

Path dir = ...;
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
    for (Path file: stream) {
        System.out.println(file.getFileName());
    }
} catch (IOException | DirectoryIteratorException x) {
    // IOException can never be thrown by the iteration.
    // In this snippet, it can only be thrown by newDirectoryStream.
    System.err.println(x);
}

Các đối tượng Path sẽ được trả về bởi các iterator là tên của các mục giải quyết đối với các thư mục. Vì vậy, nếu bạn định liệt kê các nội dung của thư mục /tmp thì các mục sẽ được trả về có dạng /tmp/a/tmp/b, ...

Phương thức này sẽ trả vè toàn bộ nội dung của một thư mục: các tập tin, liên kết, thư mục con, và các tập tin ẩn. Nếu bạn muốn có thêm nhiều lựa chọn về các nội dung được lấy ra, bạn có thể sử dụng một trong những phương thức newDirectoryStream khác, như mô tả phía dưới.

Lưu ý rằng nếu có một ngoại lệ khi lặp thư mục thì DirectoryIteratorException được ném với IOException là nguyên nhân, bởi vì các phương thức lặp không thể ném ngoại lệ.

Lọc danh sách thư mục bằng cách sử dụng globbing

Nếu bạn muốn lấy những file và thư mục con trong đó mỗi tên phù hợp với một mẫu cụ thể, thì bạn có thể làm như sau bằng cách sử dụng phương thức newDirectoryStream(Path, String), trong đó cung cấp một bộ lọc glob được xây dựng sẵn.

Ví dụ, đoạn mã sau đây liệt kê các tập tin liên quan đến Java: .class , .java và .jar:

Path dir = ...;
try (DirectoryStream<Path> stream =
     Files.newDirectoryStream(dir, "*.{java,class,jar}")) {
    for (Path entry: stream) {
        System.out.println(entry.getFileName());
    }
} catch (IOException x) {
    // IOException can never be thrown by the iteration.
    // In this snippet, it can // only be thrown by newDirectoryStream.
    System.err.println(x);
}

Ghi bộ lọc thư mục riêng của bạn

Nếu bạn muốn lọc các nội dung của một thư mục dựa trên một số điều kiện khác so với mô hình kết hợp, bạn có thể tạo bộ lọc riêng của bạn bằng cách thực thi giao diện DirectoryStream.Filter<T>. Giao diện này bao gồm một phương thức là accept, nó sẽ xác định xem một tập tin có đáp ứng các yêu cầu tìm kiếm hay không.

Ví dụ, đoạn mã sau đây thực hiện một bộ lọc chỉ để lấy các thư mục:

DirectoryStream.Filter<Path> filter =
    newDirectoryStream.Filter<Path>() {
    public boolean accept(Path file) throws IOException {
        try {
            return (Files.isDirectory(path));
        } catch (IOException x) {
            // Failed to determine if it's a directory.
            System.err.println(x);
            return false;
        }
    }
};

 

Khi bộ lọc đã được tạo ra, nó có thể được gọi bằng cách sử dụng phương thức newDirectoryStream(Path, DirectoryStream.Filter<? super Path>). Đoạn mã sau đây sử dụng bộ lọc isDirectory để chỉ in các thư mục con của thư mục tới đầu ra chuẩn:

Path dir = ...;
try (DirectoryStream<Path>
                       stream = Files.newDirectoryStream(dir, filter)) {
    for (Path entry: stream) {
        System.out.println(entry.getFileName());
    }
} catch (IOException x) {
    System.err.println(x);
}

Phương thức này được sử dụng chỉ để lọc một thư mục duy nhất. Tuy nhiên, nếu bạn muốn tìm tất cả các thư mục con trong một cây tập tin, bạn sẽ sử dụng cơ chế Đi bộ qua cây tập tin.

» Tiếp: Liên kết, liên kết tượng trưng hay không phải
« Trước: Tập tin truy cập ngẫu nhiên
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!