温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java nio内存映射怎么弄

发布时间:2026-09-22 21:39:20 来源:亿速云 阅读:92 作者:小樊 栏目:编程语言

在 Java 里,“NIO 内存映射”一般指 MappedByteBuffer,也就是把文件直接映射到内存中,通过内存操作来完成文件读写,效率比普通 IO 高很多(尤其是大文件)。

下面从 概念 → 步骤 → 示例 → 注意事项 给你讲清楚。


一、核心类

  • FileChannel:文件通道
  • MappedByteBuffer:内存映射缓冲区
  • 映射模式(FileChannel.MapMode):
    • READ_ONLY:只读
    • READ_WRITE:读写(写会同步到文件)
    • PRIVATE:私有副本(不写回文件)

二、基本使用步骤

  1. 打开文件(RandomAccessFile 或 FileInputStream / FileOutputStream)
  2. 获取 FileChannel
  3. 调用 channel.map()
  4. 像操作内存一样操作文件
  5. 最后关闭资源

三、示例代码

1️⃣ 读取文件(只读映射)

import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class MmapRead {
    public static void main(String[] args) throws Exception {
        try (RandomAccessFile file = new RandomAccessFile("test.txt", "r");
             FileChannel channel = file.getChannel()) {

            MappedByteBuffer buffer = channel.map(
                    FileChannel.MapMode.READ_ONLY,
                    0,
                    channel.size()
            );

            while (buffer.hasRemaining()) {
                System.out.print((char) buffer.get());
            }
        }
    }
}

2️⃣ 写入文件(读写映射)

import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class MmapWrite {
    public static void main(String[] args) throws Exception {
        try (RandomAccessFile file = new RandomAccessFile("test.txt", "rw");
             FileChannel channel = file.getChannel()) {

            MappedByteBuffer buffer = channel.map(
                    FileChannel.MapMode.READ_WRITE,
                    0,
                    1024 // 映射 1KB
            );

            buffer.put("Hello MappedByteBuffer".getBytes());
        }
    }
}

✅ 写完后,内容会自动同步到文件(由 OS 控制时机)


四、超大文件处理(分块映射)

map() 不能直接映射超过 Integer.MAX_VALUE 的文件,要分块:

long fileSize = channel.size();
long position = 0;
long mapSize = 1024 * 1024 * 100; // 100MB

while (position < fileSize) {
    long size = Math.min(mapSize, fileSize - position);
    MappedByteBuffer buffer = channel.map(
            FileChannel.MapMode.READ_ONLY,
            position,
            size
    );
    // 处理 buffer
    position += size;
}

五、重要注意事项(踩坑点)

⚠ 1. MappedByteBuffer 不能直接 close

  • 没有 close() 方法
  • 释放依赖 GC + Cleaner
  • 若频繁映射,可能导致:
    java.io.IOException: Too many open files
    

✅ 手动释放(不推荐但可用):

((DirectBuffer) buffer).cleaner().clean();

⚠ 2. 写入不是实时落盘

  • 由操作系统决定刷盘时机
  • 可调用:
buffer.force();

⚠ 3. 映射大小不能超 2GB

  • mapSize 是 int
  • 大文件必须分块

六、适用场景

✅ 适合:

  • 大文件随机读写
  • 高频读写
  • 数据库 / 索引文件 / 日志系统

❌ 不适合:

  • 小文件
  • 频繁创建映射
  • 需要严格事务控制

如果你愿意,我可以:

  • 给你一个 高性能读写示例
  • 对比 NIO vs Mmap 性能
  • 讲 MappedByteBuffer 的内存泄漏问题

你更想看哪一个?

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手