MappedByteBuffer

文章通过一个Server和Client的示例展示了如何使用JavaNIO的MappedByteBuffer进行文件IO操作。MappedByteBuffer允许将文件直接映射到内存,减少了磁盘和内存间的数据拷贝,提高了文件读写的效率。在Server端,接收到Client发送的数据后,直接写入MappedByteBuffer,然后强制刷新到磁盘,实现了数据的快速写入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MappedByteBuffer是ByteBuffer的子类,和ByteBuffer的使用方式类似,一般用于加速文件和内存之间的IO传输的速度,原理可理解为是给磁盘文件和app应用内存之间建立了一条快速通道,而这条快速通道就是MappedByteBuffer,通过对它的读或写就相当于对文件的读或写,不需要再经过用户态和内核态的数据来回拷贝。下面示例通过socket的传输,把client的传输的结果写到磁盘mmap.txt中

Server

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(8080));

        int lastPosition = 0;

        File file = new File("D:\\mmap.txt");
        RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
        FileChannel fileChannel = randomAccessFile.getChannel();
        //开启mmap,把文件映射到内存,对mappedByteBuffer操作即可操作文件
        MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1024);

        while (true){
            SocketChannel socketChannel = null;
            try {
                socketChannel = serverSocketChannel.accept();
                ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                int len = socketChannel.read(byteBuffer);
                if (len < 0){
                    continue;
                }
                byteBuffer.flip();
                //position指针移动到上次最后一次写入的地方
                mappedByteBuffer.position(lastPosition);
                //把client读取数据写入到mappedByteBuffer
                mappedByteBuffer.put(byteBuffer);
                //记录当前position
                lastPosition = mappedByteBuffer.position();
                //强行刷到磁盘
                mappedByteBuffer.force();

                //读出所有mappedByteBuffer的数据
                mappedByteBuffer.flip();
                byte[] dst = new byte[mappedByteBuffer.remaining()];
                mappedByteBuffer.get(dst, 0, mappedByteBuffer.remaining());
                System.out.println(new String(dst));

                byteBuffer.clear();
                mappedByteBuffer.clear();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                socketChannel.close();
            }
        }
    }
}

Client

public class Client {
    public static void main(String[] args) throws IOException {
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(8080));
        socketChannel.write(ByteBuffer.wrap("abcde".getBytes(StandardCharsets.UTF_8)));
        socketChannel.close();
    }
}

输出结果

先启动server,再执行client(3次)

abcde
abcdeabcde
abcdeabcdeabcde

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值