Java NIO 的内存映射文件(Memory-Mapped File)是通过 FileChannel.map() 把磁盘文件的一部分或全部直接映射到内存中,程序可以像访问普通内存一样读写文件,适合大文件、高性能 IO场景。
下面从 概念 → 用法 → 示例 → 注意事项 给你讲清楚。
java.nio.channels.FileChannel
java.nio.MappedByteBuffer
映射模式(FileChannel.MapMode):
| 模式 | 说明 |
|---|---|
READ_ONLY |
只读映射 |
READ_WRITE |
读写映射(会写回文件) |
PRIVATE |
写时复制(不影响文件) |
FileChannelmap() 得到 MappedByteBufferByteBuffer 一样读写import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class MmapWrite {
public static void main(String[] args) throws Exception {
RandomAccessFile file = new RandomAccessFile("test.txt", "rw");
FileChannel channel = file.getChannel();
// 映射 0~1024 字节
MappedByteBuffer buffer =
channel.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
buffer.put("Hello MappedByteBuffer".getBytes());
channel.close();
file.close();
}
}
RandomAccessFile file = new RandomAccessFile("test.txt", "r");
FileChannel channel = file.getChannel();
MappedByteBuffer buffer =
channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
System.out.println(new String(data));
✅ 减少 内核态 ↔ 用户态 拷贝
✅ 利用 OS 的 页缓存(page cache)
✅ 随机访问大文件效率高
适合:
buffer = null + System.gc() 不保证释放java.io.IOException: Map failed
✅ 解决方案:
Cleaner(反射或第三方库)示例(强制释放,谨慎使用):
Method cleaner = buffer.getClass().getMethod("cleaner");
cleaner.setAccessible(true);
Object clean = cleaner.invoke(buffer);
Method cleanMethod = clean.getClass().getMethod("clean");
cleanMethod.invoke(clean);
映射时大小是固定的:
channel.map(mode, position, size);
要扩大文件:
file.setLength(newSize);
long fileSize = channel.size();
long chunk = 1024 * 1024; // 1MB
for (long pos = 0; pos < fileSize; pos += chunk) {
long size = Math.min(chunk, fileSize - pos);
MappedByteBuffer buf =
channel.map(READ_ONLY, pos, size);
// 处理 buf
}
Java NIO 内存映射 = 把文件当内存用,快但难管。
如果你愿意,我也可以帮你:
MappedByteBuffer vs BufferedInputStream你想用在什么场景?
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。