Java NIO 中 MappedByteBuffer 將文件直接映射到內存,實現極高性能的文件讀寫;RandomAccessFile 支持隨機位置讀寫。本文對比多種方案性能並解析原理。
Buffer (abstract)
└─ ByteBuffer (abstract)
└─ MappedByteBuffer (abstract) // 文件內存映射區
// 關鍵字段:hb (byte[] 堆緩存), offset, capacity, position, limit
MappedByteBuffer 通過 FileChannel.map() 創建,映射區與文件保持同步,生命週期直到 GC 回收。
RandomAccessFile(File, "rw"):打開文件支持讀寫。getChannel():獲取 FileChannel。channel.map(MapMode.READ_WRITE, position, size):返回 MappedByteBuffer。buffer.get(i), buffer.put(i, val):直接按索引讀寫映射內存。| 方法 | 讀取 | 寫入 |
|---|---|---|
| MappedByteBuffer | 0.001s | 0.011s |
| RandomAccessFile + 自定義 byte[8KB] 緩存 | 0.0s | 0.014s |
| BufferedInputStream/OutputStream (8KB) | — | 0.585s |
結論:MappedByteBuffer 與 自定義緩存的 RandomAccessFile 性能接近且極高,遠超傳統流。緩存大小影響顯著(8KB 最優,80B 極慢)。
public class MappedByteBufferDemo {
public static void main(String[] args) throws Exception {
String src = "F:/Ebook/test.txt", dest = "F:/Ebook/test_copy.txt";
// 1. MappedByteBuffer
RandomAccessFile rafi = new RandomAccessFile(src, "r");
RandomAccessFile rafo = new RandomAccessFile(dest, "rw");
FileChannel fci = rafi.getChannel(), fco = rafo.getChannel();
long size = fci.size();
MappedByteBuffer mbbi = fci.map(FileChannel.MapMode.READ_ONLY, 0, size);
MappedByteBuffer mbbo = fco.map(FileChannel.MapMode.READ_WRITE, 0, size);
for (int i = 0; i < size; i++) mbbo.put(i, mbbi.get(i));
// 關閉資源...
// 2. RandomAccessFile + 手動緩存
byte[] buf = new byte[8192];
int len;
while ((len = rafi.read(buf)) > 0) rafo.write(buf, 0, len);
}
}
掌握 MappedByteBuffer 與緩存策略,是 Java 高性能文件處理的關鍵。