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.