Java NIO缓冲区中ByteBuffer类的使用

ByteBuffer类是Buffer类的子类,缓冲区就是在内存中预留指定大小的存储空间对I/O数据作临时存储,这部分内存空间即为缓冲区。使用缓冲区可以减少动态分配和回数内存的次数。在java NIO中,缓冲区的作用也是用来临时存储数据。缓冲区可以看作通道(channel)与客户端(或服务器)的中转站,写入数据到channel或者从channel中读取数据,这样利于数据的高效读写。
一、 Fields包装数据与获得容量
1、所有缓冲区都有四个属性:capacity、limit、position、mark,并遵循:mark <= position <= limit <= capacity,以下是对四个属性的解释。

属性描述
Capacity容量,即可以容纳的最大数据量;在缓冲区创建时被设定并且不能改变
Limit表示缓冲区的当前终点,不能对缓冲区超过极限的位置进行读写操作。且极限是可以修改的
Position位置,下一个要被读或写的元素的索引,每次读写缓冲区数据时都会改变改值,为下次读写作准备–
Mark标记,调用mark()来设置mark=position,再调用reset()可以让position恢复到标记的位置

二、Methods
1、java.nio.Buffer类是一个抽象类,不能被实例化。Buffer类的直接子类也不能被实例化,例如ByteBuffer。但是ByteBuffer类提供了4个静态工厂方法来获得ByteBuffer的实例

方法描述
allocate(int capacity)从堆空间中分配一个容量大小为capacity的byte数组作为缓冲区的byte数据存储器
allocateDirect(int capacity)分配直接缓冲区,在缓冲区较大并长期存在,或者需要经常重用时,才使用这种缓冲区
wrap(byte[] array)这个缓冲区的数据会存放在byte数组中,bytes数组或buff缓冲区任何一方中数据的改动都会影响另一方。其实ByteBuffer底层本来就有一个bytes数组负责来保存buffer缓冲区中的数据,通过allocate方法系统会帮你构造一个byte数组
wrap(byte[] array,int offset, int length)在上一个方法的基础上可以指定偏移量和长度,这个offset也就是包装后byteBuffer的position,而length呢就是limit-position的大小,从而我们可以得到limit的位置为length+position(offset)

2、ByteBuffer读写方法

方法描述
limit(), limit(10)读取和设置这4个属性的方法的命名和jQuery中的val(),val(10)类似,一个负责get,一个负责set
reset()把position设置成mark的值,相当于之前做过一个标记,现在要退回到之前标记的地方
flip()limit = position;position = 0;mark = -1; 翻转,也就是让flip之后的position到作准备limit这块区域变成之前的0到position这块,翻转就是将一个处于存数据状态的缓冲区变为一个处于准备取数据的状态
clear()position = 0;limit = capacity;mark = -1; 有点初始化的味道,但是并不影响底层byte数组的内容
get()相对读,从position位置读取一个byte,并将position+1,为下次读写作准备

三、代码示例

 byte[] byteArray = new byte[]{1, 2, 3, 4, 5, 6};
       // ByteBuffer byteBuffer = ByteBuffer.allocateDirect(10);//
        ByteBuffer byteBuffer  = ByteBuffer.wrap(byteArray);
        Log.d(TAG,"==byteBuffer=="+byteBuffer.getClass().getName());
        Log.d(TAG,"==capacity=="+byteBuffer.capacity());
        Log.d(TAG,"==limit=="+byteBuffer.limit());
        byteBuffer.limit(3);
        Log.d(TAG,"==capacity=="+byteBuffer.capacity());
        Log.d(TAG,"==limit=="+byteBuffer.limit());
        byteBuffer.put(0,(byte)7);//替换元素
        Log.d(TAG,"==byteArray=="+byteArray[0]);
        Log.d(TAG,"==position=="+byteBuffer.position(0));

输出结果:

2019-11-24 11:23:58.479 4002-4002/com.example.myapplication D/MainActivity: ==byteBuffer==java.nio.HeapByteBuffer
2019-11-24 11:23:58.479 4002-4002/com.example.myapplication D/MainActivity: ==capacity==6
2019-11-24 11:23:58.479 4002-4002/com.example.myapplication D/MainActivity: ==limit==6
2019-11-24 11:23:58.479 4002-4002/com.example.myapplication D/MainActivity: ==capacity==6
2019-11-24 11:23:58.479 4002-4002/com.example.myapplication D/MainActivity: ==limit==3
2019-11-24 11:23:58.479 4002-4002/com.example.myapplication D/MainActivity: ==byteArray==7
2019-11-24 11:23:58.479 4002-4002/com.example.myapplication D/MainActivity: ==position==java.nio.HeapByteBuffer[pos=0 lim=3 cap=6]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值