Netty初学四 数据载体ByteBuf

news/2025/2/9 5:22:06 标签: java, nio, 程序人生

一、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.示例代码:

java"> 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();
    }
}


http://www.niftyadmin.cn/n/5845543.html

相关文章

【学术投稿】第五届计算机网络安全与软件工程(CNSSE 2025)

重要信息 官网:www.cnsse.org 时间:2025年2月21-23日 地点:中国-青岛 简介 第五届计算机网络安全与软件工程(CNSSE 2025)将于2025年2月21-23日在中国-青岛举行。CNSSE 2025专注于计算机网络安全、软件工程、信号处…

初始数据结构☞复杂度与泛式

一.时间复杂度 定义: 算法的时间复杂度是一个数学函数,算法中的基本操作的执行次数,为算法的时间复杂度。 O渐进表示方法: 原因: 计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而…

从Oracle 到帆软BI:打造高效数据可视化仪表盘

从Oracle 到帆软BI:打造高效数据可视化仪表盘 在现代数据驱动的环境中,企业需要通过高效的数据可视化来洞察业务趋势和做出决策。本案例将展示如何利用帆软BI 6.1的强大功能,轻松连接到Oracle数据库,实现数据集成,并创…

MR30分布式IO模块:驱动智能制造工厂的工业互联与高效控制新范式

在工业4.0与智能制造浪潮的推动下,传统制造业正经历着从“机械驱动”向“数据驱动”的深刻转型。作为工业数据连接领域的领军者,明达技术凭借其自主研发的MR30分布式IO模块,以创新的技术架构与卓越的性能表现,为全球制造企业构建了…

Scala语言的区块链

以Scala语言的区块链 随着数字货币和去中心化应用的兴起,区块链技术逐渐成为计算机科学与金融科技领域中的一颗耀眼明星。区块链以其去中心化、不可篡改、透明可信等特性,吸引了无数开发者与企业的关注。在众多编程语言中,Scala凭借其独特的…

python学opencv|读取图像(五十九)使用cv2.dilate()函数实现图像膨胀处理

【1】引言 前序学习过程中,已经初步了解了腐蚀带来的图像处理效果,相关文章链接为: python学opencv|读取图像(五十八)使用cv2.erode()函数实现图像腐蚀处理-CSDN博客 腐蚀其实在一定程度上削减了部分像素&#xff0…

python3中字符编码的问题

记录瞬间 只要是在做开发的工作,几乎都会遇到编码的问题,恰巧最近遇到一些基本的py3编码问题,作以记述,以备不时之需。 1、十六进制与中文 第一种情况:\x开头的编码是十六进制字符,\x后面跟的字符即为十六进…

指针基础知识2

1. 指针运算 1.1 指针 - 整数 以数组举例:因为数组在内存中是连续存放的,只要知道第⼀个元素的地址,顺藤摸瓜就能找到后面的所有元素。这时就会用到指针加减整数。 1.2指针-指针 指针 - 指针可以得到两个指针之间的数据个数。但是&#xf…