[Netty] MappedByteBuffer、Buffer的分散和聚集

1. MappedByteBuffer的使用


介绍

  1. 使用MappedByteBuffer可以不在内存中将文件修改,使用堆外内存,不需要将文件进行而外的拷贝。
  2. 是一个操作系统级别的文件修改

案例

直接读取文件并修改,不进行拷贝

对1.txt文件进行读取,并直接修改其中的值。

  public static void main(String[] args) throws Exception {

        RandomAccessFile randomAccessFile = new RandomAccessFile("1.txt","rw");

        // 获取对应通道
        FileChannel channel = randomAccessFile.getChannel();

        /**
         * 参数:
         * 1. 模式:表示使用的读写模式
         * 2. 表示可以直接修改的开始位置
         * 3. 表示映射到内存的大小,即将文件的多少个字节映射到内存
         * 可以修改的范围为 [0,5)
         */
        MappedByteBuffer mappedByteBuffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 5);

        mappedByteBuffer.put(0, (byte) 'H');
        mappedByteBuffer.put(3, (byte) '8');

        
        randomAccessFile.close();

    }

效果

源文件
在这里插入图片描述
修改后文件
在这里插入图片描述


2. 分散和聚集

介绍

  1. Scattering将数据写入到buffer时,可以采用buffer数组,依次写入(一个buffer满了就写入第二个数组)被叫做分散
  2. Gattering从buffer读取数据的时候,可以采用buffer数组,依次读入 被叫做聚集

案例

使用Socket编程,模拟网络通信中的收发操作。

使用数组完成对于数据的存放和发送。

接受时,将返回结果依次放入第0个和第1个buffer中,发送时,依次从第0个和第1个数组中取出元素。
在这里插入图片描述

public class ScatteringAndGatheringTest {
    public static void main(String[] args) throws IOException {
        // 使用 ServerSocketChannel 和 SocketChannel 网络

        // 打开通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        // 定义通道未7000端口
        InetSocketAddress inetSocketAddress = new InetSocketAddress(7000);

        // 绑定通道和端口到socket
        serverSocketChannel.socket().bind(inetSocketAddress);

        // 创建buffer数组
        ByteBuffer[] byteBuffers = new ByteBuffer[2];
        byteBuffers[0] = ByteBuffer.allocate(5);
        byteBuffers[1] = ByteBuffer.allocate(3);

        // 等待客户端链接
        SocketChannel socketChannel = serverSocketChannel.accept();

        // 从客户端接受
        int messageLength = 8;
        //循环读取
        while (true) {
            int byteRead = 0;
            while (byteRead < messageLength) {
                long read = socketChannel.read(byteBuffers);
                byteRead += read;
                System.out.println("读取了" + byteRead);
                // 查看buffer的position和limit
                Arrays.asList(byteBuffers).stream().map(buffer -> "position=" + buffer.position() +
                        ",limit" + buffer.limit()).forEach(System.out::println);
            }
            // 将所有的buffer反转
            Arrays.asList(byteBuffers).stream().forEach(Buffer::flip);

            // 将数据返回给客户端
            long byteWrite = 0L;
            while (byteWrite < messageLength) {
                long write = socketChannel.write(byteBuffers);
                byteWrite += write;
            }
            // 将所有的buffer进行clear操作
            Arrays.asList(byteBuffers).forEach(Buffer::clear);
            System.out.println("byteRead:=" + byteRead + ",byteWrite=" + byteWrite + ",messageLength" + messageLength);
        }
    }
}

结果

使用Scoket调制助手,与程序程序中的7000端口建立连接。
在这里插入图片描述
发送11111字节的数据

在这里插入图片描述
看到结果如下。
在这里插入图片描述
继续发送三个1,buffer数组被填满。将数据写入buffer
在这里插入图片描述
最终结果如下
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值