AIO系列文档(1)----图解ByteBuffer
2023-09-14 09:00:09 时间
-
因何而写
网上关于bytebuffer的文章真的很多,为何在此还要写一篇呢?主要是基于以下几点考虑 -
用极易的方式认识一下bytebuffer
-
bytebuffer之第一眼印象
我们可以把bytebuffer理解成如下几个成员组成的一个新对象,对,就是一个普通的java对象,像string一样的java对象。(强调一下,这里只是说这样理解,实际上有些bytebuffer的实现类并非这样实现,并且这里只列出掌握bytebuffer所需要的最小知识集合,其它诸如mark等字段本文并不介绍,以免增加初学者的惑度)- byte[] bytes: 用来存储数据
- int capacity: 用来表示bytes的容量,那么可以想像capacity就等于bytes.size(),此值在初始化bytes后,是不可变的。
- int limit: 用来表示bytes实际装了多少数据,可以容易想像得到limit <= capacity,此值是可灵活变动的
- int position: 用来表示在哪个位置开始往bytes写数据或是读数据,此值是可灵活变动的
-
bytebuffer之常用操作及各操作对内部变量带来的变化
-
创建bytebuffer: ByteBuffer.allocate(6)
-
写入一个字节: byteBuffer.put((byte)3)
-
读取一个字节: byte bs = byteBuffer.get()
对于刚刚写好的bytebuffer,我们要读取它的内容,需要先设置一下position和limit,否则读的位置就不对
我们看一下,设置position和limit后,bytebuffer的内部变化byteBuffer.position(0); //设置position到0位置,这样读数据时就从这个位置开始读 byteBuffer.limit(1); //设置limit为1,表示当前bytebuffer的有效数据长度是1
接下来,我们就可以读取刚才写入的数据了byte bs = byteBuffer.get();
-
-
bytebuffer之使用心得
这里说的是作者本人使用bytebuffer的一些心得,这些与其说是心得,不如说是实践+测试得来的一些经验,所以并不保证就是权威的,欢迎有更深研究的朋友来合理讨论,如果有不同意见,可以以更好的论据来说服对方。-
合理灵活运用HeapByteBuffer.array()
HeapByteBuffer.array()返回的是其内部byte[],我们拿到这个后,就可以随意对这个byte[]随便操作了,可以参考t-io的SendRunnable.java的下面这段代码
注意:DirectBuffer内部是没有byte[]的,也就没有所谓的byte[]操作了。ByteBuffer allByteBuffer = ByteBuffer.allocate(allBytebufferCapacity); byte[] dest = allByteBuffer.array(); for (ByteBuffer byteBuffer : byteBuffers) { if (byteBuffer != null) { int length = byteBuffer.limit(); int position = allByteBuffer.position(); System.arraycopy(byteBuffer.array(), 0, dest, position, length); allByteBuffer.position(position + length); } }
-
jdk自带的bytebuffer已经足够好用
有一些nio/aio框架喜欢自己弄一套bytebuffer来,既增加了作者自己的工作量,又增加了用户的学习成本,但我们要知道一点,nio/aio在发送数据时,最终的参数是jdk的bytebuffer,我们真的有必要再作一次转换和计算吗?尽管某些中间过程是“零拷贝”(这个“零拷贝”也是有额外的计算成本的)的,但是jdk版bytebuffer的诞生到发送完毕,这整个过程经历了哪些操作呢?真的是如某书某博客上所说的“零拷贝”吗?更不应该把某些对象池的做法也牵强附会到“零拷贝”的概念中来----对象池属对象重复利用范畴,既然是重复利用自然便已经默认有零拷贝的属性了,但是对象池本身的维护也是需要消耗资源的,所以并不是所有场景说用了对象池,性能就提升了,有时候用不好反而增加负担,所以万事要以测试数据为准,不应盲目人云亦云!
-
-
-
最后附上bytebuffer的示例程序
这里附上bytebuffer的示例程序,用户可以自己debug观察观察,增加bytebuffer的相关概念,以便更灵活的运用bytebufferimport java.nio.ByteBuffer; /** * @author tanyaowu * 2017年5月1日 上午9:00:50 */ public class Ts { /** * * @author: tanyaowu */ public Ts() { } /** * @param args * @author: tanyaowu */ public static void main(String[] args) { ByteBuffer byteBuffer = ByteBuffer.allocate(6); byteBuffer.put((byte)3); byteBuffer.position(0); //设置position到0位置,这样读数据时就从这个位置开始读 byteBuffer.limit(1); //设置limit为1,表示当前bytebuffer的有效数据长度是1 byte bs = byteBuffer.get(); System.out.println(byteBuffer); } }
相关文章
- 最新在线接口文档管理工具推荐
- 【官方文档】《暗黑世界V1.4》API说明!
- Android BLE与终端通信(五)——Google API BLE4.0低功耗蓝牙文档解读之案例初探
- 软件开发-文档集
- OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章)
- ORACLE LINUX 6.3 + ORACLE 11.2.0.3 RAC + VBOX安装文档
- Atitit 个人信息数据文档知识分类
- Atitit.论垃圾文件的识别与清理 文档类型垃圾文件 与api概要设计pa6.doc
- 批量将网页转换成图片或PDF文档技巧分享
- (七)unity4.6Ugui中国教程文档-------摘要-UGUI Auto Layout
- FastAdmin CMS 内容管理插件标签文档
- 云计算|OpenStack|社区版OpenStack安装部署文档(六 --- 网络服务neutron的安装部署---Rocky版)