CodeGym /Các khóa học /JAVA 25 SELF /Các lớp File, Path, Files: lấy thông tin về tệp

Các lớp File, Path, Files: lấy thông tin về tệp

JAVA 25 SELF
Mức độ , Bài học
Có sẵn

1. Ôn tập: File vs Path vs Files

File xưa cũ nhưng thân thuộc

Vâng... Mã legacy trong các dự án Java không hề ít. Vì vậy hãy cùng nhắc lại về cựu binh Java — lớp File. Nó xuất hiện ngay từ phiên bản đầu tiên của ngôn ngữ và cho phép làm việc với tệp và thư mục: kiểm tra tệp có tồn tại hay không, lấy tên, kích thước, ngày sửa đổi, tạo và xóa tệp/thư mục. Như chúng ta đã biết, nó có nhiều hạn chế: một số phương thức hoạt động thiếu trực quan, không phải thao tác nào cũng được hỗ trợ đa nền tảng, và một số phương thức không ném exception mà chỉ trả về false (không phải lúc nào cũng thuận tiện cho việc gỡ lỗi).

import java.io.File;

File file = new File("example.txt");
System.out.println("Tệp có tồn tại không? " + file.exists());
System.out.println("Có phải là tệp không? " + file.isFile());
System.out.println("Có phải là thư mục không? " + file.isDirectory());

Path và Files: góc nhìn hiện đại (Java 7+)

Từ Java 7 xuất hiện gói java.nio.file, cung cấp các công cụ mạnh mẽ và linh hoạt hơn. Hai nhân vật chính:

  • Path — một interface mô tả đường dẫn tới tệp hoặc thư mục. Có thể xem nó như “chuỗi thông minh”: biết phân tách, ghép, phân tích và so sánh đường dẫn.
  • Files — lớp tiện ích với rất nhiều phương thức tĩnh để làm việc với tệp và thư mục: tạo, xóa, sao chép, đọc, ghi, lấy thông tin.
import java.nio.file.Path;
import java.nio.file.Paths;

Path path = Paths.get("example.txt");
System.out.println("Đường dẫn: " + path);

Điều thú vị: lớp Path không chỉ là một chuỗi! Nó hiểu về dấu phân tách thư mục, biết xử lý đường dẫn tương đối và tuyệt đối, và hoạt động tốt như nhau trên Windows và Linux.

Bảng so sánh File và Path/Files

Tiêu chí File (API cũ) Path + Files (API hiện đại)
Cú pháp Phong cách OOP Kết hợp Path + các phương thức tĩnh của Files
Tính đa nền tảng Một phần Rất tốt, có xét đến HĐH
Ngoại lệ Không phải lúc nào cũng có Gần như luôn có
Tính năng mới Không Có (thuộc tính, quyền, liên kết, v.v.)
Khuyến nghị Không khuyến khích

2. Lấy thông tin về tệp/thư mục

Hãy tìm hiểu cách biết những điều quan trọng nhất về tệp hoặc thư mục: nó có tồn tại hay không, loại (tệp hay thư mục), kích thước, tên, đường dẫn và thư mục cha.

Kiểm tra sự tồn tại

Qua File

File file = new File("example.txt");
if (file.exists()) {
    System.out.println("Tệp tồn tại!");
} else {
    System.out.println("Không tìm thấy tệp.");
}

Qua PathFiles

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

Path path = Paths.get("example.txt");
if (Files.exists(path)) {
    System.out.println("Tệp tồn tại!");
} else {
    System.out.println("Không tìm thấy tệp.");
}

Mẹo: Với các dự án mới, luôn sử dụng PathFiles. Điều này an toàn hơn, tiện hơn và đa nền tảng.

Kiểm tra loại: tệp hay thư mục

File

if (file.isFile()) {
    System.out.println("Đây là tệp.");
} else if (file.isDirectory()) {
    System.out.println("Đây là thư mục.");
}

Path + Files

if (Files.isRegularFile(path)) {
    System.out.println("Đây là tệp.");
} else if (Files.isDirectory(path)) {
    System.out.println("Đây là thư mục.");
}

Lấy kích thước tệp

File

long size = file.length();
System.out.println("Kích thước tệp: " + size + " byte");

Path + Files

try {
    long size = Files.size(path);
    System.out.println("Kích thước tệp: " + size + " byte");
} catch (IOException e) {
    System.out.println("Lỗi khi lấy kích thước tệp: " + e.getMessage());
}

Lưu ý: Với thư mục, phương thức length() luôn trả về 0, còn Files.size(path) sẽ ném IOException. Kích thước của một thư mục là tổng kích thước của tất cả các tệp bên trong (chi tiết sẽ có ở các bài sau).

Lấy đường dẫn tuyệt đối và tương đối

File

System.out.println("Đường dẫn tương đối: " + file.getPath());
System.out.println("Đường dẫn tuyệt đối: " + file.getAbsolutePath());

Path

System.out.println("Đường dẫn tương đối: " + path);
System.out.println("Đường dẫn tuyệt đối: " + path.toAbsolutePath());

Lấy tên tệp và thư mục cha

File

System.out.println("Tên tệp: " + file.getName());
System.out.println("Thư mục cha: " + file.getParent());

Path

System.out.println("Tên tệp: " + path.getFileName());
System.out.println("Thư mục cha: " + path.getParent());

Mẹo hay: Path có thể làm việc không chỉ với tệp mà còn với thư mục, với đường dẫn tương đối và tuyệt đối, và dễ dàng tách đường dẫn thành các phần.

3. Lấy thuộc tính tệp

Đôi khi bạn muốn biết không chỉ kích thước và tên tệp mà còn những điều thú vị hơn: ngày tạo, ngày sửa đổi gần nhất, quyền truy cập.

Ngày tạo, ngày sửa đổi gần nhất

File (bị hạn chế)

long lastModified = file.lastModified();
System.out.println("Ngày sửa đổi gần nhất: " + new java.util.Date(lastModified));

Nhược điểm: Không thể biết ngày tạo tệp thông qua File!

Path + Files

import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;

try {
    BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
    FileTime creationTime = attrs.creationTime();
    FileTime lastModifiedTime = attrs.lastModifiedTime();

    System.out.println("Ngày tạo: " + creationTime);
    System.out.println("Ngày sửa đổi gần nhất: " + lastModifiedTime);
} catch (IOException e) {
    System.out.println("Lỗi khi lấy thuộc tính: " + e.getMessage());
}

Kiểm tra quyền truy cập

File

System.out.println("Có thể đọc? " + file.canRead());
System.out.println("Có thể ghi? " + file.canWrite());
System.out.println("Có thể thực thi? " + file.canExecute());

Path + Files

System.out.println("Có thể đọc? " + Files.isReadable(path));
System.out.println("Có thể ghi? " + Files.isWritable(path));
System.out.println("Có thể thực thi? " + Files.isExecutable(path));

Điều thú vị: Trên Windows quyền truy cập bị hạn chế, còn trên các hệ thống Unix bạn có thể lấy và thay đổi nhiều quyền hơn (ví dụ, qua các thuộc tính POSIX).

4. Lỗi thường gặp khi lấy thông tin về tệp

Lỗi №1: Dùng File khi cần Path.
Nhiều người mới vẫn dùng File vì nó có vẻ đơn giản hoặc “trên mạng ai cũng làm thế”. Nhưng với PathFiles, bạn có thể làm tất cả những điều tương tự, nhưng đáng tin cậy và hiện đại hơn.

Lỗi №2: Chỉ kiểm tra loại đối tượng qua File.
Nếu bạn chỉ dùng file.isFile()file.isDirectory(), bạn có thể bỏ sót các tệp “đặc biệt” (liên kết tượng trưng, thiết bị). Trong API hiện đại có Files.isRegularFile(path), Files.isDirectory(path) và các kiểm tra khác.

Lỗi №3: Bỏ qua exception.
Các phương thức Files.size(path)Files.readAttributes(...) ném IOException. Nếu không xử lý exception, chương trình sẽ sập ngay khi gặp lỗi truy cập đầu tiên hoặc khi tệp biến mất trong lúc chạy.

Lỗi №4: Mong đợi có thể lấy kích thước thư mục trực tiếp.
Với thư mục, phương thức Files.size(path) sẽ ném exception. Để biết kích thước thư mục, cần đệ quy cộng kích thước của tất cả các tệp bên trong.

Lỗi №5: Kiểm tra quyền truy cập chưa đầy đủ.
Ngay cả khi tệp tồn tại, bạn có thể không có quyền đọc hoặc ghi. Luôn kiểm tra quyền trước khi thao tác: Files.isReadable(path), Files.isWritable(path), Files.isExecutable(path).

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION