Netty初学四 数据载体ByteBuf

一、ByteBuf的结构:

        1.结构图:

        从上图可以看出,该结构是一个字节容器,里面的数据分为三部分,第一部分是已经丢弃的字节,这部分的数据是无效的,第二部分是可读字节,这部分数据是该结构的主题数据,最后一部分为可写字节,后面虚线部分表示该结构还可以扩容多少

        具体分析,该结构包括两个指针,分别是读指针和写指针,每读一个字节,readerinsex就自增1,其中总共有writeIndex-readerIndex个字节可读,由此,当读写指针指向一个位置时表示不可读,写指针同理,但是该指针是当其增加到capacity时表示不可写

        另外,当该结构写数据时容量不足时会自动进行扩容,如果容器真实的容量大小和最大容量大小(maxCapacity)相等时就会暂停,超过之后就不报错

        2.容量API

        capacity():表示bytebuf底层占用了多少字节

        maxcapacity():表示该结构底层最多能够占用多大的字节的内存

        readableBytes()与isReadable():分别表示当前可读的字节和是否可读,即读写指针是否一致,一致则isReadable()会返回false

        writeableBytes()  iswriteable()  maxWriteable():分别表示当前可写的数据,以及是否可写和当前可写的最大字节数

        3.读写指针相关的API

        readerIndex()  readerIndex(int):前者返回当前的读指针,后者表示设置读指针

        writeIndex() writeIndex(int):前者表示返回写指针,后者表示设置写指针

        markReaderIndex()  resetReaderIndex():前者表示保存当前的读指针,后者表示把当前的读指针恢复到之前保存的值

        markWriterIndex()  resetWriterIndex():同理read相关的API

        4.读写API

        writeBytes(bytes[] src)  buffer.readBytes(byte[] dst): 前者表示把字节数组src里面的数据全部写到ByteBuf中,后者时把ByteBuf中的数据全部读取到dst中,其大小为readableBytes()

        release()与retain():因为Netty使用的是堆外内存并且是不被jvm直接管理申请到的内存无法被垃圾回收器直接回收,需要手动回收,否则会造成内存泄漏

        slice()  duplicate()  copy():第一个方法是截取readerIndex到writeIndex之间,并且返回的ByteBuf的最大容量是原始的readableBytes(),第二个方法是把整个ByteBuf都截取出来,前两个方法的相同点是底层是与原始的ByteBuf共享,即经过返回的ByteBuf的对象调用write方法都会影响到原始的ByteBuf,但是它们维持的与原始的读写指针不同的指针,最后一个方法会直接从原始的ByteBuf中复制信息

        retainedSlice()  retainedDuplicate():这两个方法的作用是截取内存片段的同时会增加内存的引用计数

        5.示例代码:

 public class ByteBufTest {
public static void main(String[] args) {
   ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer(9, 100);
        print("allocate ByteBuf(9, 100)", buffer);
        // write方法改变写指针,写完之后写指针未到capacity的时候,
buffer仍然可写
        buffer.writeBytes(new byte[]{1, 2, 3, 4});
        print("writeBytes(1,2,3,4)", buffer);
        // write方法改变写指针,写完之后写指针未到capacity的时候,
buffer仍然可写,写完int
类型之后,写指针增加4
        buffer.writeInt(12);
        print("writeInt(12)", buffer);
        // write方法改变写指针,写完之后写指针等于capacity的时候,
buffer不可写
        buffer.writeBytes(new byte[]{5});
print("writeBytes(5)", buffer);
// write方法改变写指针,写的时候发现buffer不可写则开始扩容,扩容
之后capacity随即改变
buffer.writeBytes(new byte[]{6});
print("writeBytes(6)", buffer);
// get方法不改变读写指针
System.out.println("getByte(3) return: " + buffer.getByte(3));
System.out.println("getShort(3) return: " + buffer.getShort(3));
System.out.println("getInt(3) return: " + buffer.getInt(3));
print("getByte()", buffer);
// set方法不改变读写指针
buffer.setByte(buffer.readableBytes() + 1, 0);
print("setByte()", buffer);
// read方法改变读指针
byte[] dst = new byte[buffer.readableBytes()];
buffer.readBytes(dst);
print("readBytes(" + dst.length + ")", buffer);
}
private static void print(String action, ByteBuf buffer) {
System.out.println("after ===========" + action + "============
 ");
System.out.println("capacity(): " + buffer.capacity());
System.out.println("maxCapacity(): " + buffer.maxCapacity());
   System.out.println("readerIndex(): " + buffer.readerIndex());
        System.out.println("readableBytes(): " + buffer.readableBytes());
        System.out.println("isReadable(): " + buffer.isReadable());
        System.out.println("writerIndex(): " + buffer.writerIndex());
        System.out.println("writableBytes(): " + buffer.writableBytes());
        System.out.println("isWritable(): " + buffer.isWritable());
        System.out.println("maxWritableBytes(): " + buffer.maxWritableByte
 s());
        System.out.println();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值