NIO之Buffer原理介绍

在这里插入图片描述

可以看到java为除boolean外的每一种类型都准备了一个对应的Buffer类
当然,如果要到网络上传输必须得是byte

字段功能
mark用于标记某次读/写的位置,可用reset()回到这里
position下一个读写的位置
limit第一个不应该读/写的索引位置,position < limit
capacityBuffer能够存放的最大容量

在这里插入图片描述
我们来看ByteBuffer,它有两个主要的子类,DirectByteBuffer和HeapByteBuffer,DirectByteBuffer使用的是直接内存,HeapByteBuffer用的是堆内存

这里我们以HeapByteBuffer为例

在这里插入图片描述
我们可以看到里面有个字节数组叫hb,它就是buffer实际上的存储实现,我们读/写的数据都要经过这个数组。offset是偏移量,一般字节为1

Buffer数据结构

前面提到,简单的说Buffer就是一个封装好的数组,刚初始化的时候,limit和capacity相同
position指向数组头部,mark为-1(只有手动使用过mark()方法mark才会变)。
在这里插入图片描述

初始化->对Buffer写

在这里插入图片描述
写就是从position索引处开始写,每写一个字节,position就+1(注意position是要写入的索引位置)

// 对应代码
public ByteBuffer put(byte x) {
        checkSegment();
        // 若position超出limit则抛出异常
        hb[ix(nextPutIndex())] = x;
        return this;
    }
    
// 若当前位置超出limit则抛出异常
final int nextPutIndex() {                          // package-private
        if (position >= limit)
            throw new BufferOverflowException();
        // position加1
        return position++;
    }
写->读

当需要读/写转换时,需要执行flip()方法

public Buffer flip() {
        limit = position;
        position = 0;
        mark = -1;
        return this;
    }

在这里插入图片描述
我们可以注意到,limit就是写的最后一个位置,而现在position为0,我们读取数据只能从索引position读到limit,这种限制保证了读取的数据不会越界

读->写(读完了)

若我们是在读取到limit之后才执行flip(),则直接重置就可以了,没啥好说的

读->写(没读完)

若我们需要在读完之前就转换读/写,就要使用compact()函数

public ByteBuffer compact() {
        int pos = position();
        int rem = limit() - pos;
        // 转移还没读完的数据
        System.arraycopy(hb, ix(pos), hb, ix(0), rem);
        position(rem);
        limit(capacity());
        discardMark();
        return this;
    }

compoact()的作用是把还未读完的数据转移到数组开头,并把position置为转移后的未读完数据的下一个索引
在这里插入图片描述

其实你会发现,这几个方法,完全没用到mark,mark需要根据场景手动调用mark()函数

简单使用示例

在这里插入图片描述
在这里插入图片描述
参考:
Buffer中读模式和写模式的切换

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值