java bytebuffer 大小_Java NIO之ByteBuffer的介绍和使用

ByteBuffer类位于java.nio包下,所谓nio:代表new io,另一种解释:N代表Non-blocking IO,非阻塞的IO

Buffer是一个抽象的基类

派生类:ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer

Buffer的几个基本属性

基础属性,使用ByteBuffer是以字节Byte为基础的,操作对象是字节

capacity--Buffer的容量,读取数据的限制和读取数据的位置,capacity 是分配好的一个内存块大小,分配好后大小不可变

limit--在读的模式下,表示缓存内数据的多少,limit<=capacity; 在写的模式下,表示最多能存入多少数据,此时limit=capacity;简单说:在Buffer上进行的读写操作都不能越过这个下标。

position--表示读写的位置,下标从0开始

Buffer的几个方法

clear()--position置为0,limit转为capacity大小,标记mark也会被清除

flip()--limit被置为当前position的大小,也就是说后续的读操作可能会被限制,这是与clear()有区别的地方;然后position被置为0

rewind()--position置为0,标记被取消

使用举例

基本用法

ByteBuffer byteBuffer = ByteBuffer.allocate(10);//分配10个字节大小的缓存

byteBuffer.putInt(5);//int占用4个字节

byteBuffer.put((byte) 1);//1个字节

byteBuffer.put((byte) 0);//1个字节

byteBuffer.put("abc".getBytes());//2个字节

System.out.printf("position: %d, limit: %d, capacity: %d\n", buf.position(), buf.limit(), buf.capacity());

打印结果:

position: 9, limit: 10, capacity: 10

分析:byteBuffer刚开始分配了10个字节的缓存,放入一个Int值5,占用4个字节,两个byte数又占两个,adb占用三个字节,总共占用了9个字节。从打印结果中看到,position为9表示已经存储了9个字节即下标0-8,limit表示在写模式下最多存储10个字节,capacity为10表示缓存容量为10。

java.nio.BufferOverflowException

因为ByteBuffer的大小不可变的,所以如果存储的长度超过capacity,那么就会抛出java.nio.BufferOverflowException异常,表示缓冲区上溢出,写入的位置超出了内存长度。

flip()和clear()

flip方法的作用是先将limit属性设置为当前的position的值,再将position转为0,并清除标记。

clear方法的不同之处是limit=capacity。

ByteBuffer byteBuffer = ByteBuffer.allocate(10);

byteBuffer.putInt(5);//int占用4个字节

byteBuffer.put((byte) 1);

byteBuffer.put((byte) 0);

byteBuffer.put("abcd".getBytes());

printByteBuffer(byteBuffer);

// 读取消息头,因为写完后position已经到10了,所以需要先反转为0,再从头读取

byteBuffer.flip();//将position置0

//需要按顺序读取,position自增

System.out.printf("读取int值: %d\n", byteBuffer.getInt());//读int

System.out.printf("读取byte值: %d\n", byteBuffer.get());//读byte

System.out.printf("读取byte值: %d\n", byteBuffer.get());//读byte

byte[] str = new byte[4];

byteBuffer.get(str, 0, 4);//连续读4个字节,并保存到str中,注意第二个参数是相对于position的偏移量

System.out.println("读取字符串=" + new String(str));

打印结果如下:

position: 10, limit: 10, capacity: 10

读取int值: 5

读取byte值: 1

读取byte值: 0

读取字符串=abcd

java.nio.BufferUnderflowException

试一下flip()的使用。上面介绍中提到,flip()的作用是先将limit属性设置为当前的position的值,再将position转为0。也就是说如果当前的position是小于实际保存的字节长度的,那么下次就最多读取到这个position的位置,如果超出则会抛出异常。

ByteBuffer byteBuffer = ByteBuffer.allocate(10);

byteBuffer.putInt(5);//int占用4个字节

byteBuffer.put((byte) 1);

byteBuffer.put((byte) 0);

byteBuffer.put("abcd".getBytes());

byteBuffer.clear();

//先读取一个int,再flip()

System.out.printf("读取int值: %d\n", byteBuffer.getInt());//读int

byteBuffer.flip();

System.out.printf("position: %d, limit: %d, capacity: %d\n", byteBuffer.position(), byteBuffer.limit(), byteBuffer.capacity());

//需要按顺序读取,position自增

System.out.printf("读取int值: %d\n", byteBuffer.getInt());//读int

System.out.printf("读取byte值: %d\n", byteBuffer.get());//读byte

System.out.printf("读取byte值: %d\n", byteBuffer.get());//读byte

打印结果:

读取int值: 5

position: 0, limit: 4, capacity: 10

读取int值: 5

java.nio.BufferUnderflowException

at java.nio.Buffer.nextGetIndex(Buffer.java:500)

at java.nio.HeapByteBuffer.get(HeapByteBuffer.java:135)

at com.heima.ajax.JacksonTest.testByteBuffer(JacksonTest.java:83)

此时报出了内存下溢出的异常,说明读取的位置超出了限制。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值