Quản lý Siêu dữ liệu (Thuộc tính Tệp và Lưu trữ Tệp)
Managing Metadata (File and File Store Attributes)

Metadata (siêu dữ liệu) là dữ liệu mô tả thông tin về các dữ liệu khác. Trong hệ thống tệp, dữ liệu chứa trong các tệp và thư mục, và metadata theo dõi thông tin về từng đối tượng: Nó là tệp bình thường, thư mục hay liên kết? Kích thước của nó là bao nhiêu, ngày tạo, ngày sửa đổi cuối cùng, chủ sở hữu tệp, nhóm chủ sở hữu, và quyền truy cập?

Metadata của hệ thống tệp thường được gọi là thuộc tính tệp. Lớp Files bao gồm các phương thức có thể được sử dụng để lấy một thuộc tính của tệp, hoặc để thiết lập một thuộc tính.

Các phương thức kiểm tra Metadata

Trong Java, Metadata của tệp và thư mục bao gồm các thông tin như kích thước, loại tệp, hoặc thuộc tính đặc biệt. Lớp Files cung cấp nhiều phương thức để kiểm tra các thông tin này. Dưới đây là một số phương thức phổ biến giúp bạn dễ dàng kiểm tra Metadata của tệp và thư mục.

↳ static long size(Path): Trả về kích thước của tệp được chỉ định tính bằng byte.

↳ static boolean isDirectory(Path, LinkOption): Trả về true nếu Path chỉ định một thư mục.

↳ static boolean isRegularFile(Path, LinkOption...): Trả về true nếu Path chỉ định một tệp bình thường.

↳ static boolean isSymbolicLink(Path): Trả về true nếu Path chỉ định một liên kết biểu tượng (symbolic link).

↳ static boolean isHidden(Path): Trả về true nếu Path chỉ định một tệp được coi là ẩn bởi hệ thống tệp.

↳ static FileTime getLastModifiedTime(Path, LinkOption...): Trả về thời gian sửa đổi cuối cùng của tệp được chỉ định.

↳ static Path setLastModifiedTime(Path, FileTime): Đặt thời gian sửa đổi cuối cùng của tệp.

↳ static UserPrincipal getOwner(Path, LinkOption...): Trả về chủ sở hữu của tệp.

↳ static Path setOwner(Path, UserPrincipal): Đặt chủ sở hữu của tệp.

↳ static Set<PosixFilePermission> getPosixFilePermissions(Path, LinkOption...): Trả về quyền truy cập POSIX của tệp.

↳ static Path setPosixFilePermissions(Path, Set<PosixFilePermission>): Đặt quyền truy cập POSIX của tệp.

↳ static Object getAttribute(Path, String, LinkOption...): Trả về giá trị của thuộc tính tệp.

↳ static Path setAttribute(Path, String, Object, LinkOption...): Đặt giá trị của thuộc tính tệp.

↳ static <V extends FileAttributeView>V getFileAttributeView(Path path, Class<V> type, LinkOption... options): Trả về một view của các thuộc tính của file theo một kiểu cụ thể.

↳ static FileStore getFileStore(Path path): Trả về đối tượng FileStore đại diện cho nơi lưu trữ của file.

Nếu chương trình cần nhiều thuộc tính tệp cùng một lúc, việc sử dụng các phương thức lấy một thuộc tính có thể không hiệu quả. Việc truy cập hệ thống tệp nhiều lần để lấy từng thuộc tính có thể ảnh hưởng đến hiệu suất. Để giải quyết điều này, lớp Files cung cấp hai phương thức readAttributes để lấy thuộc tính tệp trong một lần thao tác.

Các phương thức đọc thuộc tính

Các phương thức đọc thuộc tính trong Java giúp bạn truy xuất thông tin chi tiết về tệp hoặc thư mục một cách linh hoạt và hiệu quả. Dưới đây là hai phương thức phổ biến:

↳ static Map<String,Object> readAttributes(Path, String, LinkOption...): Đọc thuộc tính của tệp dưới dạng một thao tác khối. Tham số String xác định các thuộc tính cần đọc.

↳ static <A extends BasicFileAttributes>A readAttributes(Path, Class<A>, LinkOption...): Đọc thuộc tính của tệp dưới dạng một thao tác khối. Tham số Class<A> là loại thuộc tính yêu cầu và phương thức trả về một đối tượng của loại đó.

Trước khi xem các ví dụ về các phương thức readAttributes, cần lưu ý rằng các hệ thống tệp khác nhau có những quan điểm khác nhau về việc nên theo dõi những thuộc tính nào. Vì lý do này, các thuộc tính tệp liên quan được nhóm lại thành các chế độ xem (views). Một chế độ xem ánh xạ đến một triển khai hệ thống tệp cụ thể, chẳng hạn như POSIX hoặc DOS, hoặc đến một chức năng chung, chẳng hạn như quyền sở hữu tệp.

Các chế độ xem thuộc tính hỗ trợ

Các chế độ xem thuộc tính tệp (File Attribute Views) hỗ trợ việc lấy và thiết lập các thuộc tính khác nhau của tệp. Dưới đây là các chế độ xem thuộc tính tệp được hỗ trợ:

↳ BasicFileAttributeView: Cung cấp chế độ xem các thuộc tính cơ bản mà mọi triển khai hệ thống tệp đều phải hỗ trợ. Các thuộc tính cơ bản bao gồm kích thước, thời gian sửa đổi cuối cùng, và kiểu tệp (tệp bình thường, thư mục, liên kết biểu tượng).

↳ DosFileAttributeView: Mở rộng chế độ xem thuộc tính cơ bản với các thuộc tính tiêu chuẩn bốn bit được hỗ trợ trên các hệ thống tệp hỗ trợ thuộc tính DOS. Ví dụ, các thuộc tính DOS như "ẩn", "chỉ đọc", "hệ thống", và "tệp tạm thời".

↳ PosixFileAttributeView: Mở rộng chế độ xem thuộc tính cơ bản với các thuộc tính được hỗ trợ trên các hệ thống tệp hỗ trợ chuẩn POSIX, chẳng hạn như UNIX. Các thuộc tính này bao gồm chủ sở hữu tệp, nhóm chủ sở hữu, và chín quyền truy cập liên quan.

↳ FileOwnerAttributeView: Được hỗ trợ bởi bất kỳ triển khai hệ thống tệp nào hỗ trợ khái niệm chủ sở hữu tệp. Cho phép lấy và thiết lập chủ sở hữu của tệp.

↳ AclFileAttributeView: Hỗ trợ việc đọc hoặc cập nhật Danh Sách Kiểm Soát Truy Cập (ACL) của tệp. Mô hình ACL NFSv4 được hỗ trợ. Bất kỳ mô hình ACL nào, chẳng hạn như mô hình ACL của Windows, có ánh xạ rõ ràng đến mô hình NFSv4 cũng có thể được hỗ trợ.

↳ UserDefinedFileAttributeView: Cho phép hỗ trợ metadata do người dùng định nghĩa. Chế độ xem này có thể được ánh xạ đến bất kỳ cơ chế mở rộng nào mà hệ thống hỗ trợ. Ví dụ, trong Solaris OS, bạn có thể sử dụng chế độ xem này để lưu trữ loại MIME của một tệp.

Một triển khai hệ thống tệp cụ thể có thể chỉ hỗ trợ chế độ xem thuộc tính tệp cơ bản hoặc có thể hỗ trợ nhiều chế độ xem thuộc tính tệp khác nhau. Một số hệ thống tệp có thể hỗ trợ các chế độ xem thuộc tính khác không được bao gồm trong API này.

Trong hầu hết các trường hợp, bạn không cần phải làm việc trực tiếp với bất kỳ giao diện FileAttributeView nào. (Nếu bạn cần làm việc trực tiếp với FileAttributeView, bạn có thể truy cập nó thông qua phương thức getFileAttributeView(Path, Class<V>, LinkOption...)).

Các phương thức readAttributes sử dụng generic và có thể được sử dụng để đọc các thuộc tính cho bất kỳ chế độ xem thuộc tính tệp nào. Các ví dụ trong phần tiếp theo của trang này sử dụng các phương thức readAttributes.

Phần còn lại của phần này bao gồm các chủ đề sau:

↳ Các thuộc tính cơ bản của tệp tin

↳ Thiết lập thời gian cập nhật cuối cùng

↳ Thuộc tính tệp DOS

↳ Thiết lập chủ sở hữu tệp hoặc nhóm

↳ Thuộc tính file được định nghĩa bởi người dùng

↳ Thuộc tính của Store File


Ⅰ. Các thuộc tính cơ bản của tệp tin

Để đọc các thuộc tính cơ bản của một tệp, bạn có thể sử dụng một trong các phương thức Files.readAttributes, phương thức này đọc tất cả các thuộc tính cơ bản trong một lần thao tác. Điều này hiệu quả hơn nhiều so với việc truy cập hệ thống tệp riêng biệt để đọc từng thuộc tính. Tham số varargs hiện tại hỗ trợ enum LinkOption, với tùy chọn NOFOLLOW_LINKS. Sử dụng tùy chọn này khi bạn không muốn theo dõi các liên kết biểu tượng.

Một lưu ý về thời gian: Tập hợp các thuộc tính cơ bản bao gồm ba thời gian: creationTime, lastModifiedTime, và lastAccessTime. Bất kỳ thời gian nào trong số này có thể không được hỗ trợ trong một triển khai cụ thể, trong trường hợp đó phương thức truy cập tương ứng sẽ trả về một giá trị đặc thù cho triển khai. Khi được hỗ trợ, thời gian sẽ được trả về dưới dạng đối tượng FileTime.

Dưới đây là đoạn mã ví dụ đọc và in các thuộc tính cơ bản của một tệp sử dụng các phương thức trong lớp BasicFileAttributes:

Ví dụ: Example.java

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;

public class Example {
    public static void main(String[] args) {
        // Định nghĩa đường dẫn của tệp cần đọc thuộc tính
        Path filePath = Paths.get("D:\\baitapjava\\Example.txt");

        try {
            // Đọc các thuộc tính cơ bản của tệp
            BasicFileAttributes attrs = Files.readAttributes(filePath, BasicFileAttributes.class);
            
            // In các thuộc tính cơ bản
            System.out.println("Thời gian tạo: " + attrs.creationTime());
            System.out.println("Thời gian sửa đổi lần cuối: " + attrs.lastModifiedTime());
            System.out.println("Thời gian truy cập lần cuối : " + attrs.lastAccessTime());
            System.out.println("Là Thư mục: " + attrs.isDirectory());
            System.out.println("Là Tệp thông thường: " + attrs.isRegularFile());
            System.out.println("Là Liên kết tượng trưng: " + attrs.isSymbolicLink());
            System.out.println("Kích thước: " + attrs.size() + " bytes");
        } catch (IOException e) {
            // Xử lý lỗi khi đọc thuộc tính tệp
            System.err.println("Lỗi khi đọc thuộc tính tệp: " + e.getMessage());
        }
    }
}

Kết quả của chương trình là:

Thời gian tạo: 2024-07-20T01:06:34.2882852Z
Thời gian sửa đổi lần cuối: 2024-08-16T12:44:41.2044817Z
Thời gian truy cập lần cuối : 2024-08-17T10:48:12.8749372Z
Là Thư mục: false
Là Tệp thông thường: true
Là Liên kết tượng trưng: false
Kích thước: 126 bytes

Lưu ý:

↳ Các thuộc tính thời gian có thể không được hỗ trợ trong một số hệ thống tệp, và trong trường hợp đó, phương thức truy cập tương ứng có thể trả về giá trị mặc định.

↳ Ngoài các phương thức truy cập được hiển thị trong ví dụ này, còn có phương thức fileKey() trả về một đối tượng duy nhất xác định tệp hoặc null nếu không có khóa tệp nào có sẵn.

↳ Thay thế "path/to/your/file.txt" bằng đường dẫn thực tế đến tệp mà bạn muốn thao tác.

Ⅱ. Thiết lập thời gian cập nhật cuối cùng

Để đặt thời gian sửa đổi cuối cùng của một tệp, bạn có thể sử dụng phương thức Files.setLastModifiedTime(Path, FileTime). Dưới đây là đoạn mã ví dụ cho thấy cách thiết lập thời gian sửa đổi cuối cùng của một tệp bằng số mili giây hiện tại:

Ví dụ: Example.java

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileTime;

public class Example {
    public static void main(String[] args) {
        // Định nghĩa đường dẫn của tệp cần thay đổi thời gian sửa đổi
        Path filePath = Paths.get("path/to/your/file.txt");

        try {
            // Lấy thời gian hiện tại tính bằng mili giây
            long currentTimeMillis = System.currentTimeMillis();
            
            // Tạo đối tượng FileTime từ thời gian hiện tại
            FileTime fileTime = FileTime.fromMillis(currentTimeMillis);
            
            // Đặt thời gian sửa đổi cuối cùng cho tệp
            Files.setLastModifiedTime(filePath, fileTime);
            
            System.out.println("Thời gian sửa đổi cuối cùng đã được cập nhật.");
        } catch (IOException e) {
            // Xử lý lỗi khi không thể thay đổi thời gian sửa đổi của tệp
            System.err.println("Lỗi khi cập nhật thời gian sửa đổi cuối cùng: " + e.getMessage());
        }
    }
}

Đoạn mã trên sẽ cập nhật thời gian sửa đổi cuối cùng của tệp với thời gian hiện tại, giúp bạn kiểm soát và thay đổi thông tin liên quan đến thời gian sửa đổi của tệp.

Lưu ý: Thay thế "path/to/your/file.txt" bằng đường dẫn thực tế đến tệp mà bạn muốn thao tác.

Ⅲ. Thuộc tính tệp DOS

DOS là viết tắt của "Disk Operating System" là hệ điều hành máy tính đầu tiên sử dụng đĩa mềm và đĩa cứng để lưu trữ dữ liệu. Hệ điều hành DOS phổ biến nhất là MS-DOS (Microsoft Disk Operating System), được phát triển bởi Microsoft và là hệ điều hành chính cho các máy tính cá nhân trước khi Windows trở thành phổ biến.

Thuộc tính tệp DOS cũng được hỗ trợ trên các hệ thống tệp khác ngoài DOS, chẳng hạn như Samba. Thuộc tính tệp DOS cung cấp thông tin về các thuộc tính bổ sung của tệp như chỉ đọc, ẩn, hệ thống và lưu trữ. Để đọc các thuộc tính DOS của một tệp, bạn có thể sử dụng lớp DosFileAttributes. Dưới đây là một đoạn mã ví dụ cho thấy cách sử dụng các phương thức của lớp DosFileAttributes để đọc các thuộc tính này:

Ví dụ: Example.java

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.DosFileAttributes;

public class Example {
    public static void main(String[] args) {
        // Định nghĩa đường dẫn của tệp cần kiểm tra thuộc tính DOS
        Path filePath = Paths.get("path/to/your/file.txt");

        try {
            // Đọc các thuộc tính DOS của tệp
            DosFileAttributes dosAttrs = Files.readAttributes(filePath, DosFileAttributes.class);
            
            // In các thuộc tính DOS của tệp
            System.out.println("Tệp: " + filePath.toString());
            System.out.println("Chỉ đọc: " + dosAttrs.isReadOnly());
            System.out.println("Ẩn: " + dosAttrs.isHidden());
            System.out.println("Hệ thống: " + dosAttrs.isSystem());
            System.out.println("Lưu trữ: " + dosAttrs.isArchive());
        } catch (IOException e) {
            // Xử lý lỗi khi không thể đọc thuộc tính DOS của tệp
            System.err.println("Lỗi khi đọc thuộc tính DOS của tệp: " + e.getMessage());
        }
    }
}

Đoạn mã trên giúp bạn kiểm tra các thuộc tính DOS của tệp, điều này có thể hữu ích khi bạn cần làm việc với các thuộc tính bổ sung ngoài các thuộc tính cơ bản của tệp.

Lưu ý: Thay thế "path/to/your/file.txt" bằng đường dẫn thực tế đến tệp mà bạn muốn thao tác.

Đặt thuộc tính DOS

Để thiết lập thuộc tính DOS của một tệp, bạn có thể sử dụng phương thức Files.setAttribute(Path, String, Object, LinkOption...). Dưới đây là một ví dụ về cách sử dụng phương thức này để thiết lập các thuộc tính DOS của tệp, chẳng hạn như thuộc tính chỉ đọc, ẩn, hệ thống và lưu trữ:

Ví dụ: Example.java

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.DosFileAttributeView;

public class Example {
    public static void main(String[] args) {
        // Định nghĩa đường dẫn của tệp cần thay đổi thuộc tính DOS
        Path filePath = Paths.get("path/to/your/file.txt");

        try {
            // Lấy đối tượng DosFileAttributeView để thay đổi thuộc tính DOS
            DosFileAttributeView dosView = Files.getFileAttributeView(filePath, DosFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
            
            if (dosView != null) {
                // Thiết lập thuộc tính chỉ đọc
                Files.setAttribute(filePath, "dos:readonly", true, LinkOption.NOFOLLOW_LINKS);
                
                // Thiết lập thuộc tính ẩn
                Files.setAttribute(filePath, "dos:hidden", true, LinkOption.NOFOLLOW_LINKS);
                
                // Thiết lập thuộc tính hệ thống
                Files.setAttribute(filePath, "dos:system", true, LinkOption.NOFOLLOW_LINKS);
                
                // Thiết lập thuộc tính lưu trữ
                Files.setAttribute(filePath, "dos:archive", true, LinkOption.NOFOLLOW_LINKS);

                System.out.println("Đã thiết lập thuộc tính DOS cho tệp thành công.");
            } else {
                System.err.println("Không thể lấy thuộc tính DOS của tệp.");
            }
        } catch (IOException e) {
            // Xử lý lỗi khi không thể thiết lập thuộc tính DOS của tệp
            System.err.println("Lỗi khi thiết lập thuộc tính DOS của tệp: " + e.getMessage());
        }
    }
}

Đoạn mã trên giúp bạn thiết lập thuộc tính DOS cho tệp, điều này có thể hữu ích khi bạn cần thay đổi các thuộc tính bổ sung ngoài các thuộc tính cơ bản của tệp.

Lưu ý: Thay thế "path/to/your/file.txt" bằng đường dẫn thực tế đến tệp mà bạn muốn thao tác.

Ⅳ. Thiết lập chủ sở hữu tệp hoặc nhóm

Để thiết lập chủ sở hữu file hoặc nhóm, bạn có thể sử dụng dịch vụ UserPrincipalLookupService để tra cứu tên và chuyển đổi nó thành đối tượng UserPrincipal hoặc GroupPrincipal. Dưới đây là cách thực hiện điều này:

Thiết lập chủ sở hữu File

Để thiết lập chủ sở hữu của một file, bạn cần thực hiện các bước sau:

↳ Tra cứu UserPrincipal: Sử dụng dịch vụ UserPrincipalLookupService để tra cứu tên người dùng và nhận được đối tượng UserPrincipal tương ứng.

↳ Thiết lập chủ sở hữu: Sử dụng phương thức Files.setOwner để gán đối tượng UserPrincipal cho file.

Dưới đây là ví dụ mã để thực hiện việc này:

Ví dụ: Example.java

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.UserPrincipal;
import java.nio.file.attribute.UserPrincipalLookupService;
import java.nio.file.attribute.UserPrincipalNotFoundException;

public class Example {
    public static void main(String[] args) {
        Path filePath = Paths.get("path/to/your/file.txt"); // Đường dẫn tới tệp mà bạn muốn thay đổi chủ sở hữu
        String newOwner = "username"; // Thay đổi tên người dùng theo yêu cầu

        try {
            // Lấy dịch vụ tra cứu UserPrincipal từ hệ thống tệp mặc định
            UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService();
            
            // Tra cứu UserPrincipal từ tên người dùng
            UserPrincipal newOwnerPrincipal = lookupService.lookupPrincipalByName(newOwner);

            // Thiết lập chủ sở hữu mới cho tệp
            Files.setOwner(filePath, newOwnerPrincipal);

            System.out.println("Đã thay đổi chủ sở hữu của tệp thành công.");
        } catch (UserPrincipalNotFoundException e) {
            System.err.println("Tên người dùng không tồn tại: " + e.getMessage());
        } catch (IOException e) {
            System.err.println("Lỗi khi thay đổi chủ sở hữu của tệp: " + e.getMessage());
        }
    }
}

Đoạn mã trên giúp bạn thay đổi chủ sở hữu của một tệp, điều này có thể hữu ích khi cần quản lý quyền sở hữu của tệp trên hệ thống tệp.

Lưu ý: Thay thế "path/to/your/file.txt" bằng đường dẫn thực tế đến tệp mà bạn muốn thao tác.

Thiết lập nhóm sở hữu

Để thiết lập nhóm sở hữu file, bạn cần sử dụng PosixFileAttributeView vì không có phương thức đặc biệt trong lớp Files để làm điều này trực tiếp. Các bước thực hiện:

↳ Tra cứu GroupPrincipal: Sử dụng dịch vụ UserPrincipalLookupService để tra cứu tên nhóm và nhận được đối tượng GroupPrincipal tương ứng.

↳ Thiết lập nhóm sở hữu: Sử dụng phương thức setGroup của PosixFileAttributeView để gán nhóm sở hữu cho file.

Dưới đây là ví dụ mã để thực hiện việc này:

Ví dụ: Example.java

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.GroupPrincipal;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.UserPrincipalLookupService;
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.Set;

public class Example {
    public static void main(String[] args) {
        Path filePath = Paths.get("path/to/your/file.txt"); // Đường dẫn đến tệp mà bạn muốn thay đổi nhóm sở hữu
        String newGroup = "groupname"; // Tên nhóm mới

        try {
            // Lấy dịch vụ tra cứu GroupPrincipal từ hệ thống tệp mặc định
            UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService();
            
            // Tra cứu GroupPrincipal từ tên nhóm
            GroupPrincipal newGroupPrincipal = (GroupPrincipal) lookupService.lookupPrincipalByGroupName(newGroup);

            // Lấy thuộc tính POSIX của tệp
            PosixFileAttributeView posixView = Files.getFileAttributeView(filePath, PosixFileAttributeView.class);
            if (posixView == null) {
                System.err.println("Hệ thống tệp không hỗ trợ thuộc tính POSIX.");
                return;
            }

            // Thiết lập nhóm sở hữu mới cho tệp
            posixView.setGroup(newGroupPrincipal);

            System.out.println("Đã thay đổi nhóm sở hữu của tệp thành công.");
        } catch (IOException e) {
            System.err.println("Lỗi khi thay đổi nhóm sở hữu của tệp: " + e.getMessage());
        }
    }
}

Lưu ý:

↳ Đảm bảo rằng bạn có quyền cần thiết để thay đổi thuộc tính của file hoặc nhóm.

↳ Đảm bảo rằng hệ thống tệp hỗ trợ thuộc tính POSIX, vì PosixFileAttributeView chỉ có sẵn trên các hệ thống tệp hỗ trợ POSIX (như Linux hoặc macOS).

↳ Phương thức lookupPrincipalByGroupName có thể không có sẵn trong tất cả các triển khai. Bạn cần đảm bảo rằng hệ thống tệp của bạn hỗ trợ chức năng này hoặc điều chỉnh mã sao cho phù hợp với môi trường của bạn.

↳ Thay thế "path/to/your/file.txt" bằng đường dẫn thực tế đến tệp mà bạn muốn thao tác.

Ⅴ. Thuộc tính file được định nghĩa bởi người dùng

Khi các thuộc tính file do hệ thống file hỗ trợ không đáp ứng đủ nhu cầu của bạn, bạn có thể sử dụng UserDefinedFileAttributeView để tạo và theo dõi các thuộc tính file của riêng mình.

Một số hệ thống file ánh xạ khái niệm này vào các tính năng như NTFS Alternative Data Streams và thuộc tính mở rộng trên các hệ thống file như ext3 và ZFS. Hầu hết các triển khai đều có giới hạn về kích thước của giá trị; chẳng hạn, ext3 giới hạn kích thước là 4 kilobytes.

Lưu trữ thuộc tính MIME Type

Để lưu trữ MIME type của một file như là thuộc tính do người dùng định nghĩa, bạn có thể sử dụng đoạn mã sau:

Ví dụ: Example.java

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.UserDefinedFileAttributeView;
import java.util.List;

public class Example {
    public static void main(String[] args) {
        Path filePath = Paths.get("path/to/your/file.txt"); // Đường dẫn đến tệp bạn muốn thêm thuộc tính
        String mimeType = "text/plain"; // MIME type bạn muốn lưu trữ
        
        // Lưu trữ thuộc tính MIME type
        try {
            // Lấy UserDefinedFileAttributeView từ tệp
            UserDefinedFileAttributeView view = Files.getFileAttributeView(filePath, UserDefinedFileAttributeView.class);
            if (view == null) {
                System.err.println("Hệ thống tệp không hỗ trợ thuộc tính do người dùng định nghĩa.");
                return;
            }
            
            // Ghi thuộc tính MIME type vào tệp
            view.write("user:mimeType", java.nio.charset.StandardCharsets.UTF_8.encode(mimeType));
            System.out.println("Đã lưu trữ MIME type thành công.");
            
            // Đọc thuộc tính MIME type từ tệp
            List<String> attributeNames = view.list();
            if (attributeNames.contains("user:mimeType")) {
                byte[] buffer = new byte[view.size("user:mimeType")];
                view.read("user:mimeType", java.nio.ByteBuffer.wrap(buffer));
                String readMimeType = new String(buffer, java.nio.charset.StandardCharsets.UTF_8);
                System.out.println("Đã đọc MIME type: " + readMimeType);
            } else {
                System.out.println("Không có thuộc tính MIME type trong tệp.");
            }
        } catch (IOException e) {
            System.err.println("Lỗi khi thao tác với thuộc tính tệp: " + e.getMessage());
        }
    }
}

Lưu ý:

↳ Đảm bảo rằng hệ thống tệp của bạn hỗ trợ thuộc tính do người dùng định nghĩa. Một số hệ thống tệp có thể không hỗ trợ hoặc có thể có giới hạn về kích thước của thuộc tính.

↳ Đoạn mã này giả định rằng hệ thống tệp hỗ trợ các thuộc tính do người dùng định nghĩa và cho phép lưu trữ dữ liệu kiểu chuỗi.

↳ Thay thế "path/to/your/file.txt" bằng đường dẫn thực tế đến tệp mà bạn muốn thao tác.

Đọc thuộc tính MIME Type

Để đọc thuộc tính MIME type từ một tệp, bạn có thể sử dụng UserDefinedFileAttributeView để truy cập và đọc thuộc tính đã được lưu trữ trước đó. Dưới đây là ví dụ về cách thực hiện điều này:

Ví dụ: Example.java

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.UserDefinedFileAttributeView;
import java.nio.ByteBuffer;

public class Example {
    public static void main(String[] args) {
        Path filePath = Paths.get("path/to/your/file.txt"); // Đường dẫn đến tệp bạn muốn đọc thuộc tính

        try {
            // Lấy UserDefinedFileAttributeView từ tệp
            UserDefinedFileAttributeView view = Files.getFileAttributeView(filePath, UserDefinedFileAttributeView.class);
            if (view == null) {
                System.err.println("Hệ thống tệp không hỗ trợ thuộc tính do người dùng định nghĩa.");
                return;
            }

            // Kiểm tra xem thuộc tính MIME type có tồn tại không
            if (view.list().contains("user:mimeType")) {
                // Đọc kích thước thuộc tính MIME type
                int size = view.size("user:mimeType");
                
                // Đọc thuộc tính MIME type vào byte buffer
                ByteBuffer buffer = ByteBuffer.allocate(size);
                view.read("user:mimeType", buffer);
                buffer.flip(); // Chuyển buffer từ chế độ ghi sang chế độ đọc
                
                // Chuyển đổi buffer thành chuỗi
                String mimeType = new String(buffer.array(), java.nio.charset.StandardCharsets.UTF_8);
                System.out.println("MIME type của tệp là: " + mimeType);
            } else {
                System.out.println("Không có thuộc tính MIME type trong tệp.");
            }
        } catch (IOException e) {
            System.err.println("Lỗi khi thao tác với thuộc tính tệp: " + e.getMessage());
        }
    }
}

Lưu ý:

↳ Đảm bảo hệ thống tệp hỗ trợ thuộc tính do người dùng định nghĩa và có khả năng lưu trữ các giá trị kiểu chuỗi.

↳ Thuộc tính MIME type phải được lưu trữ trước đó bằng cách sử dụng UserDefinedFileAttributeView.

↳ Thay thế "path/to/your/file.txt" bằng đường dẫn thực tế đến tệp mà bạn muốn thao tác.

Xóa thuộc tính định nghĩa bởi người dùng

Để xóa một thuộc tính do người dùng định nghĩa trên một tệp, bạn có thể sử dụng phương thức remove của lớp UserDefinedFileAttributeView. Dưới đây là ví dụ về cách thực hiện việc này:

Ví dụ: Example.java

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.UserDefinedFileAttributeView;

public class Example {
    public static void main(String[] args) {
        Path filePath = Paths.get("path/to/your/file.txt"); // Đường dẫn đến tệp bạn muốn xóa thuộc tính

        try {
            // Lấy UserDefinedFileAttributeView từ tệp
            UserDefinedFileAttributeView view = Files.getFileAttributeView(filePath, UserDefinedFileAttributeView.class);
            if (view == null) {
                System.err.println("Hệ thống tệp không hỗ trợ thuộc tính do người dùng định nghĩa.");
                return;
            }

            // Kiểm tra xem thuộc tính có tồn tại không
            if (view.list().contains("user:mimeType")) {
                // Xóa thuộc tính
                view.delete("user:mimeType");
                System.out.println("Đã xóa thuộc tính MIME type.");
            } else {
                System.out.println("Thuộc tính MIME type không tồn tại.");
            }
        } catch (IOException e) {
            System.err.println("Lỗi khi thao tác với thuộc tính tệp: " + e.getMessage());
        }
    }
}

Lưu ý:

↳ Đảm bảo hệ thống tệp hỗ trợ thuộc tính do người dùng định nghĩa và có khả năng xóa thuộc tính.

↳ Cần có quyền thích hợp để xóa thuộc tính của tệp.

↳ Thay thế "path/to/your/file.txt" bằng đường dẫn thực tế đến tệp mà bạn muốn thao tác.

Ⅵ. Thuộc tính của Store File

Bạn có thể sử dụng lớp FileStore để tìm hiểu thông tin về một store file, chẳng hạn như bao nhiêu không gian còn lại. Phương thức getFileStore(Path) giúp lấy thông tin về store file cho file cụ thể.

Dưới đây là đoạn mã để in thông tin về việc sử dụng không gian của store file nơi một file cụ thể nằm:

Ví dụ: Example.java

import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.Files;
import java.nio.file.Path;

public class Example {
    public static void main(String[] args) {
        Path filePath = Path.of("path/to/your/file.txt");

        try {
            // Lấy thông tin FileStore cho file cụ thể
            FileStore fileStore = Files.getFileStore(filePath);

            // In ra thông tin về việc sử dụng không gian của FileStore
            System.out.println("Chi tiết kho lưu trữ tệp:");
            System.out.println("Loại: " + fileStore.type());
            System.out.println("Tổng dung lượng: " + fileStore.getTotalSpace() + " bytes");
            System.out.println("Dung lượng có thể sử dụng: " + fileStore.getUsableSpace() + " bytes");
            System.out.println("Dung lượng chưa phân bổ: " + fileStore.getUnallocatedSpace() + " bytes");
        } catch (IOException e) {
            System.err.println("Lỗi khi truy cập kho lưu trữ tệp: " + e.getMessage());
        }
    }
}

Đoạn mã trên cung cấp cái nhìn tổng quan về việc sử dụng không gian trên hệ thống lưu trữ của tệp cụ thể.

Ví dụ về DiskUsage

Ví dụ sau đây sử dụng API này để in thông tin về không gian đĩa cho tất cả các store file trong hệ thống file mặc định. Ví dụ này sử dụng phương thức getFileStores trong lớp FileSystem để lấy tất cả các store file của hệ thống file:

Ví dụ: Example.java

import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;

public class Example {
    public static void main(String[] args) {
        // Lấy hệ thống file mặc định
        FileSystem fileSystem = FileSystems.getDefault();

        // Duyệt qua tất cả các FileStore trong hệ thống file
        for (FileStore fileStore : fileSystem.getFileStores()) {
            try {
                // In thông tin về FileStore
                System.out.println("Lưu trữ tệp: " + fileStore);
                System.out.println("Loại: " + fileStore.type());
                System.out.println("Tổng dung lượng: " + fileStore.getTotalSpace() + " bytes");
                System.out.println("Dung lượng có thể sử dụng: " + fileStore.getUsableSpace() + " bytes");
                System.out.println("Dung lượng chưa phân bổ: " + fileStore.getUnallocatedSpace() + " bytes");
                System.out.println();
            } catch (IOException e) {
                System.err.println("Lỗi khi truy cập kho lưu trữ tệp: " + e.getMessage());
            }
        }
    }
}

Kết quả của chương trình là:

Lưu trữ tệp: (C:)
Loại: NTFS
Tổng dung lượng: 214748360704 bytes
Dung lượng có thể sử dụng: 80469176320 bytes
Dung lượng chưa phân bổ: 80469176320 bytes

Lưu trữ tệp: Work (D:)
Loại: NTFS
Tổng dung lượng: 25185595392 bytes
Dung lượng có thể sử dụng: 15800008704 bytes

Đoạn mã này giúp bạn kiểm tra và hiển thị thông tin không gian đĩa cho tất cả các hệ thống lưu trữ được gán trong hệ thống file hiện tại.

Hy vọng rằng qua các ví dụ trên, bạn sẽ hiểu rõ hơn về cách quản lý siêu dữ liệu trong Java.

Câu Nói Truyền Cảm Hứng

“Bắt đầu ở đâu không quan trọng, quan trọng là bạn sẵn sàng bắt đầu.” – W. Clement Stone

Không Gian Tích Cực

“Chúc bạn luôn giữ vững niềm tin và sức mạnh để vượt qua mọi thử thách trong cuộc sống.”