Tệp Tin Truy Cập Ngẫu Nhiên
(Random Access Files)

Tệp truy cập ngẫu nhiên cho phép bạn đọc từ và ghi vào các vị trí tùy ý trong một tệp, thay vì chỉ đọc hoặc ghi tuần tự từ đầu đến cuối tệp. Chức năng này được cung cấp bởi Interface SeekableByteChannel trong Java, một phần của gói NIO (New I/O).

Interface SeekableByteChannel

Interface SeekableByteChannel kế thừa (extends) interface ByteChannel cơ bản với khả năng di chuyển đến một vị trí cụ thể trong tệp. Các phương thức chính bao gồm:

↳ position(): Trả về vị trí hiện tại của kênh.

↳ position(long newPosition): Đặt vị trí của kênh ở giá trị được chỉ định.

↳ read(ByteBuffer dst): Đọc byte từ kênh vào bộ đệm được chỉ định.

↳ write(ByteBuffer src): Ghi byte từ bộ đệm được chỉ định vào kênh.

↳ truncate(long size): Cắt tệp đến kích thước được chỉ định.

Dưới đây là ví dụ chi tiết về cách sử dụng Interface SeekableByteChannel để đọc, ghi và thêm dữ liệu vào một tệp:

Ví dụ: Example.java

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public class Example {
    public static void main(String[] args) {
        Path path = Path.of("example.txt");

        // Tạo hoặc mở tệp để đọc và ghi
        try (SeekableByteChannel channel = Files.newByteChannel(path, 
                                                                  StandardOpenOption.CREATE, 
                                                                  StandardOpenOption.WRITE, 
                                                                  StandardOpenOption.READ)) {

            // Viết dữ liệu vào tệp
            String content = "Hello, SeekableByteChannel!";
            ByteBuffer buffer = ByteBuffer.wrap(content.getBytes());
            channel.write(buffer);
            
            // Di chuyển vị trí đến đầu tệp để đọc dữ liệu từ đầu
            channel.position(0);
            
            // Đọc dữ liệu từ tệp
            buffer.clear();  // Xóa bộ đệm trước khi đọc
            channel.read(buffer);
            buffer.flip();   // Chuyển bộ đệm từ chế độ ghi sang chế độ đọc
            
            // Hiển thị nội dung đã đọc
            byte[] data = new byte[buffer.remaining()];
            buffer.get(data);
            System.out.println("Dữ liệu đọc từ tệp: " + new String(data));
            
            // Di chuyển vị trí đến cuối tệp và thêm dữ liệu
            channel.position(channel.size());  // Di chuyển đến cuối tệp
            String additionalContent = " Appended data.";
            ByteBuffer appendBuffer = ByteBuffer.wrap(additionalContent.getBytes());
            channel.write(appendBuffer);
            
            // Đọc lại dữ liệu sau khi thêm
            channel.position(0);  // Di chuyển đến đầu tệp để đọc lại toàn bộ dữ liệu
            buffer.clear();  // Xóa bộ đệm
            channel.read(buffer);
            buffer.flip();
            
            // Hiển thị nội dung đã đọc sau khi thêm dữ liệu
            data = new byte[buffer.remaining()];
            buffer.get(data);
            System.out.println("Dữ liệu đọc từ tệp sau khi thêm: " + new String(data));
            
            // Cắt tệp chỉ còn phần nội dung ban đầu
            channel.truncate(content.length());
            channel.position(0);  // Di chuyển về đầu tệp để đọc lại dữ liệu sau khi cắt
            buffer.clear();
            channel.read(buffer);
            buffer.flip();
            
            // Hiển thị nội dung đã đọc sau khi cắt
            data = new byte[buffer.remaining()];
            buffer.get(data);
            System.out.println("Dữ liệu đọc từ tệp sau khi cắt bớt: " + new String(data));

        } catch (IOException e) {
            System.err.println("Đã xảy ra lỗi I/O: " + e.getMessage());
        }
    }
}

Lưu ý:

↳ Interface SeekableByteChannel cho phép bạn đọc và ghi dữ liệu ở bất kỳ vị trí nào trong tệp mà không cần phải đọc hoặc ghi tuần tự.

↳ Phương thức truncate(long size) cắt tệp đến kích thước chỉ định, giữ lại nội dung từ đầu đến vị trí đó và loại bỏ phần còn lại.

Hy vọng rằng qua các ví dụ trên, bạn sẽ hiểu rõ hơn về cách truy cập tệp tin ngẫu nhiên 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.”