ByteBuf用法

ByteBuf用法JDKNIO之ByteBuffer的局限性如下:(1)长度固定,一旦分配完成,它的容量将不能动态扩展和收缩,而需要编码的POJO对象大雨ByteBuffer的容量时,会发生索引越界异常;(2)只有一个标识位置的指针position,读写的是偶需要搜公条用flip()和rewind()等,使用着必须小心的处理这些API,否则很容易导致程序越界异常;(3)ByteBuffer的API功能有限,…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

JDK NIO之ByteBuffer的局限性如下:
(1)长度固定,一旦分配完成,它的容量将不能动态扩展和收缩,而需要编码的POJO对象大雨ByteBuffer的容量时,会发生索引越界异常;
(2)只有一个标识位置的指针position,读写的是偶需要搜公条用flip()和rewind()等,使用着必须小心的处理这些API,否则很容易导致程序越界异常;
(3)ByteBuffer的API功能有限,一些高级和实用扽特性不支持,需要使用者自己编程实现、
为了弥补这些不足,Netty提供了自己的缓冲区实现ByteBuf。

ByteBuf通过两个位置指针来协助缓冲的读写操作:读指针:readerIndex和写指针writerIndex

   ByteBuf可以分为两类:

(1)对内存:HeapByteBuf自己缓冲区,特点是内存的分配和回收速度快,可以被JVM自动回收,,缺点是如果使用Socket的IO读写,需要额外做一次内存复制,将堆内存对应的额缓冲区复制到内核Channel中,性能会有一定的下降。

(2)直接内存。DirectByteBuf字节缓冲区也可以叫做直接缓冲区,非堆内存。它在堆外进行内存分配,相比于堆内存,它的分配和回收速度会慢一些。但是将它写入或者从SocketChannel中读取时,由于少了一次内存复制。速度比堆内存要快。

因此Netty提供了多种ByteBuf 的实现共开发者选择。在长期的开发实践中,表明,在IO通信线程的读写缓冲区使用DirectByteBuf, 后端业务消息的编解码模块使用HeapByteBuf,这样组合可以达到性能最优。

1、readerIndex、writerIndex 读写索引

ByteBuf用法

 //初始化ByteBuf,读写索引都为0;
 ByteBuf buf = Unpooled.buffer(10);//非池化10字节大小的ByteBuf
 System.out.println(buf.toString());//UnpooledHeapByteBuf(ridx: 0, widx: 0, cap: 10)
 System.out.println( Arrays.toString(buf.array()));//[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
 
 //写入5个字节的数组,写索引变为5;
 byte[] bytes = {1,2,3,4,5};
 buf.writeBytes(bytes);
 System.out.println(buf.toString());//UnpooledHeapByteBuf(ridx: 0, widx: 5, cap: 10)
 System.out.println(Arrays.toString(buf.array()));//[1, 2, 3, 4, 5, 0, 0, 0, 0, 0]

 //读取两个字节,写索引为5,读索引2
 byte b1 = buf.readByte();
 byte b2 = buf.readByte();
 System.out.println(Arrays.toString(new byte[]{b1,b2}));
 System.out.println(buf.toString());//UnpooledHeapByteBuf(ridx: 2, widx: 5, cap: 10)
 System.out.println(Arrays.toString(buf.array()));//[1, 2, 3, 4, 5, 0, 0, 0, 0, 0]

 //将读取的内容丢弃后,读索引0,写索引(5-2)=3
 buf.discardReadBytes();//将读取的内容丢弃
 System.out.println(buf.toString());//UnpooledHeapByteBuf(ridx: 0, widx: 3, cap: 10)
 System.out.println(Arrays.toString(buf.array()));//[3, 4, 5, 4, 5, 0, 0, 0, 0, 0]

 System.out.println(buf.readableBytes());//返回可读字节的个数;  3
 System.out.println(buf.writableBytes());//返回可写字节的个数;  7

//清空读写指针,读写指针都为0,clear并不会清空缓冲区内容本身,主要用来操作指针;
 buf.clear();
 System.out.println(buf.toString());//UnpooledHeapByteBuf(ridx: 0, widx: 0, cap: 10)
 System.out.println(Arrays.toString(buf.array()));//[3, 4, 5, 4, 5, 0, 0, 0, 0, 0]

 //再次写入一段内容
 byte[] bytes2 = {1,2,3};
 buf.writeBytes(bytes2);
 buf.readByte();
 System.out.println(Arrays.toString(bytes2));
 System.out.println(buf.toString());//UnpooledHeapByteBuf(ridx: 1, widx: 3, cap: 10)
 System.out.println(Arrays.toString(buf.array()));//[1, 2, 3, 4, 5, 0, 0, 0, 0, 0]

 // 将ByteBuf清零,读写索引都不变
 buf.setZero(0,buf.capacity());
 System.out.println(buf.toString());//UnpooledHeapByteBuf(ridx: 1, widx: 3, cap: 10)
 System.out.println(Arrays.toString(buf.array()));//[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]


Charset utf8 = Charset.forName("UTF-8");
ByteBuf buf1 = Unpooled.copiedBuffer("Netty in Action rocks!", utf8);
ByteBuf sliced = buf1.slice(0, 14);
ByteBuf copy = buf1.copy(0, 14);
System.out.println(buf1.toString(utf8));//Netty in Action rocks!
System.out.println("是否支持访问数组:"+buf1.hasArray());//false  访问非堆缓冲区ByteBuf的数组会导致UnsupportedOperationException,因此下面的访问方式会报错

//System.out.println(Arrays.toString(buf1.array()));
System.out.println(sliced.toString(utf8));//Netty in Actio
//System.out.println(Arrays.toString(sliced.array()));
System.out.println(copy.toString(utf8));//Netty in Actio
//System.out.println(Arrays.toString(copy.array()));

buf1.setByte(0, (byte)'J');//get和set操作读写指定索引的数据,而不会改变索引值。read和write操作读写指定索引数据,并且会改变索引的值
System.out.println(buf1.toString(utf8));//Jetty in Action rocks!
//由于数据是共享的,对一个ByteBuf的修改对原始的ByteBuf是可见的
System.out.println(sliced.toString(utf8));//Jetty in Actio
//copy方法会重新分配新的ByteBuf,对其的修改对原始的ByteBuf不可见。
System.out.println(copy.toString(utf8));//Netty in Actio
System.out.println(buf1.getByte(0)==sliced.getByte(0));//true
System.out.println(buf1.getByte(0)==copy.getByte(0));//false

   

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/191884.html原文链接:https://javaforall.net

(0)
上一篇 2026年1月23日 下午2:43
下一篇 2026年1月23日 下午3:15


相关推荐

  • 新浪微博爬虫分享(一天可抓取 1300 万条数据)「建议收藏」

    From:https://blog.csdn.net/bone_ace/article/details/50903178微博爬虫单机每日千万级的数据微博爬虫总结:https://blog.csdn.net/nghuyong/article/details/81251948Python爬虫——新浪微博(网页版):https://blog.csdn.net/qq_37267015/ar…

    2022年4月15日
    54
  • raid0 raid1 raid5 raid6 raid10的优缺点和做各自raid需要几块硬盘[通俗易懂]

    raid0 raid1 raid5 raid6 raid10的优缺点和做各自raid需要几块硬盘[通俗易懂]一、Raid0:一块硬盘或者以上就可做raid0优势:数据读取写入最快,最大优势提高硬盘容量,比如3块80G的硬盘做raid0可用总容量为240G。速度是一样。缺点:无冗余能力,一块硬盘损坏,数据全无。建议:做raid0可以提供更好的容量以及性能,推荐对数据安全性要求不高的使用。二、Raid1:至少2快硬盘可做raid1优势:镜像,数据安全强,2快硬盘做raid一块正常运行,另外一块镜像备份数据,保障数据的安全。一块坏了,另外一块硬盘也有完整的数据,保障运行。缺…

    2022年7月15日
    20
  • 遗传算法代码

    遗传算法代码全局搜索最优算法 1 遗传算法这里以 github 上的遗传算法开源库为例子 首先我们安装 GA 官方说依赖库好像只支持 Python3 但是我好像 python2 也安装成功了 pip3installp 在这里我们讨论一个简单的全局优化过程 讨论 x 2 2 y 4 2 x 2 2 y 4 2 x 2 2 y 4 2 在 x 1 5 y 6 9 x subset 1 5 y subset 6 9 x 1 5 y 6 9 的最大值 源码如下 importnump

    2026年3月18日
    2
  • Cursor实战:从0到1快速打造你的第一个微信小程序

    Cursor实战:从0到1快速打造你的第一个微信小程序

    2026年3月16日
    3
  • idea使用步骤_idea怎么编译maven项目

    idea使用步骤_idea怎么编译maven项目1.下载MybatisCodeHelperPro首先我们打开IDEA,点击file,再点击setting,找到Plugins,我们可以从marketplace中下载MybatisCodeHelperPro。2.安装MybatisCodeHelperPro有时候我们打不开marketplace,这时候我们就需要手动安装MybatisCodeHelperPro,我们点击右上角的小齿轮,选择第三项,选择我们的MybatisCodeHelperPro的压缩包,无需解压。然后我们重启IDEA,这里

    2026年2月6日
    5
  • 三角剖分详解

    三角剖分详解三角剖分技术在图形领域 尤其是在三维重建领域是非常非常重要的技术 就拿我现在正在从事的 3D 打印行业来说吧 如果复杂曲面的三角剖分能够得以解决 那么我们这个行当绝大部分看似复杂的软件问题 都能轻易解决 因为对于提取点云 不管是硬件还是软件 成本是低廉的 要说三角剖分 首先要从 Delaunay 说起 它是目前三角剖分理论的基础 很多三维的剖分优化准则实际上是对它的扩展 Delaunay 三角网法则

    2026年3月18日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号