首页 > 其他分享 >【转载】aio系列文档(2)----图解bytebuffer

【转载】aio系列文档(2)----图解bytebuffer

时间:2022-09-01 11:59:12浏览次数:83  
标签:ByteBuffer bytebuffer ---- aio limit byteBuffer position byte

aio系列文档(2)----图解bytebuffer  收藏 原作者: talent-tan

  1. 因何而写

    网上关于bytebuffer的文章真的很多,为何在此还要写一篇呢?主要是基于以下几点考虑
    1. 很多人在使用t-io时,还不会bytebuffer,只会照着t-io提供的例子照猫画虎,不利于灵活运用
    2. 网上搜到的一些相关文章,讲得不是太易懂,不利于初学者灵活运用bytebuffer
    3. 本文旨在讲解灵活运用bytebuffer所需的最小知识,以帮助用户快速掌握bytebuffer
  2. 用极易的方式认识一下bytebuffer

    1. bytebuffer之第一眼印象

      我们可以把bytebuffer理解成如下几个成员组成的一个新对象,对,就是一个普通的java对象,像string一样的java对象。(强调一下,这里只是说这样理解,实际上有些bytebuffer的实现类并非这样实现,并且这里只列出掌握bytebuffer所需要的最小知识集合,其它诸如mark等字段本文并不介绍,以免增加初学者的惑度
      1. byte[] bytes: 用来存储数据
      2. int capacity: 用来表示bytes的容量,那么可以想像capacity就等于bytes.size(),此值在初始化bytes后,是不可变的。
      3. int limit: 用来表示bytes实际装了多少数据,可以容易想像得到limit <= capacity,此值是可灵活变动的
      4. int position: 用来表示在哪个位置开始往bytes写数据或是读数据,此值是可灵活变动的
      通过下图,对bytebuffer形成一个感观认识吧
    2. bytebuffer之常用操作及各操作对内部变量带来的变化

      1. 创建bytebuffer: ByteBuffer.allocate(6)

      2. 写入一个字节: byteBuffer.put((byte)3)

      3. 读取一个字节: byte bs = byteBuffer.get()

        对于刚刚写好的bytebuffer,我们要读取它的内容,需要先设置一下position和limit,否则读的位置就不对
        
        byteBuffer.position(0);  //设置position到0位置,这样读数据时就从这个位置开始读
        byteBuffer.limit(1);     //设置limit为1,表示当前bytebuffer的有效数据长度是1
        
        我们看一下,设置position和limit后,bytebuffer的内部变化

        接下来,我们就可以读取刚才写入的数据了
        
        byte bs = byteBuffer.get();
        

    3. bytebuffer之使用心得

      这里说的是作者本人使用bytebuffer的一些心得,这些与其说是心得,不如说是实践+测试得来的一些经验,所以并不保证就是权威的,欢迎有更深研究的朋友来合理讨论,如果有不同意见,可以以更好的论据来说服对方。
      1. 合理灵活运用HeapByteBuffer.array()

        HeapByteBuffer.array()返回的是其内部byte[],我们拿到这个后,就可以随意对这个byte[]随便操作了,可以参考t-io的SendRunnable.java的下面这段代码
        
        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);
        	}
        }
        
        注意:DirectBuffer内部是没有byte[]的,也就没有所谓的byte[]操作了。
      2. jdk自带的bytebuffer已经足够好用

        有一些nio/aio框架喜欢自己弄一套bytebuffer来,既增加了作者自己的工作量,又增加了用户的学习成本,但我们要知道一点,nio/aio在发送数据时,最终的参数是jdk的bytebuffer,我们真的有必要再作一次转换和计算吗?尽管某些中间过程是“零拷贝”(这个“零拷贝”也是有额外的计算成本的)的,但是jdk版bytebuffer的诞生到发送完毕,这整个过程经历了哪些操作呢?真的是如某书某博客上所说的“零拷贝”吗?更不应该把某些对象池的做法也牵强附会到“零拷贝”的概念中来----对象池属对象重复利用范畴,既然是重复利用自然便已经默认有零拷贝的属性了,但是对象池本身的维护也是需要消耗资源的,所以并不是所有场景说用了对象池,性能就提升了,有时候用不好反而增加负担,所以万事要以测试数据为准,不应盲目人云亦云!
  3. 最后附上bytebuffer的示例程序

    这里附上bytebuffer的示例程序,用户可以自己debug观察观察,增加bytebuffer的相关概念,以便更灵活的运用bytebuffer
    
    import 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);
    	}
    }
    
 

标签:ByteBuffer,bytebuffer,----,aio,limit,byteBuffer,position,byte
From: https://www.cnblogs.com/ecba/p/16646022.html

相关文章

  • 不信谣不传谣,亲自动手验证ModelBox推理是否真的“高性能”
    摘要:“高性能推理”是ModelBox宣传的主要特性之一,不信谣不传谣的我决定通过原生API和ModelBox实现相同案例进行对比,看一下ModelBox推理是否真的“高性能”。本文分享自华......
  • spi的工作方式
    DMA MODE3 SPI四种模式区别-百度文库(baidu.com) ......
  • go map键类型小记
    一、Go语言map的键类型不可以是函数类型、字典类型和切片类型。因为map键值需要可以做hash操作,而func,map,slice不支持这些操作。 报错:  并且,一般Struct可以支持ha......
  • 【瞎口胡】单位根反演
    单位根反演是用单位根来表示整除关系的东西。定义式\[\left[k\midn\right]=\dfrac{1}{k}\sum\limits_{i=0}^{k-1}\omega_k^{in}\]如果\(k\midn\),那么\(\omeg......
  • .Net6 Api 里使用版本控制(Versioning)
    NetCoreApi接口版本管理简单介绍感谢创建ASP.NETCoreWebApi本次操作环境条件创建项目versioning的版本控制的方法第一步,通过Nuget安装包第二步,在Startup.cs里的Con......
  • 如何在Windows电脑桌面上添加待办提醒工具?
    国内的绝大多数上班族使用的办公电脑都是Windows系统的,而一款便捷、实用的软件能够在我们工作中起到事半功倍的作用,所以大家对于各类实用的软件需求量是很大的。那么你有......
  • 区间 kth
    众所周知,区间kth有很多种求法。本文中的时间复杂度和分数均以实现P3834为准。为了更好地贴合现实,本文代码将更加符合学此算法时的实际情况。一、排序通过选择/冒......
  • 一次较波折的MySQL调优
    春节长假某日,阳光明媚,春暖花开,恰逢冬奥会开幕,想着一定是一个黄道吉日,必能顺风顺水。没想到却遇到一个有点小波折的客户报障。01故障起因故障起因是客户前一天从自建MySQ......
  • UML设计图6-序列图
    1.基本概念序列图(SequenceDiagram)是对象之间基于时间顺序的动态交互,它显示出了随着时间的变化对象之间是如何进行通讯的。序列图的主要用途之一是从一定程度上更加详细地......
  • LC238
    /*使用双指针,左指针指向当前已经处理好的序列的尾部,右指针指向待处理序列的头部。右指针不断向右移动,每次右指针指向非零数,则将左右指针对应的数交换,同时左指针右移。*/......