Buffer(缓冲区)是一个包装了基本数据元素数组的对象,提供了比数组更加丰富API操作数据。
1.属性
Buffer有四个基本属性:
1、capacity 容量,buffer能够容纳的最大元素数目,在Buffer创建时设定并不能更改
2、limit buffer中有效位置数目
3、position 下一个读或者写的位置
4、mark 用于记忆的标志位,配合reset()使用,初始值未设定,调用mark()方法后将当前position设为mark的值
四者关系:0 <= mark <= position <= limit <= capacity
2.基本操作
1
访问,通过get(),get(index),其中get()从当前position位置读取,get(index)从index位置读取,不改变当前position,下面要说到的put也一样;
2 填充,通过put(byte),put(index,byte),按照绝对位置填充也是不改变当前position属性
3 flip ,通过buffer.flip() 设置limit=postion,postion=0。因为向缓冲区put数据之后,会导致postion和limit的改变,为了使能读取buffer的所有数据,一般在读取之前,调用flip()函数。
4 判断数据:buff.remaining(); 返回剩余的数据数量。buff.hasRemaining();是否有数据。
5 clear:buff.clear() ,将缓冲区设置成初始状态。postion=0,limit=capacity 。
6 compact()方法,用于压缩buffer,这个方法在多次重复调用时是比较低效。把当前读写位置之后的数据复制到内部存储空间的最前面。同时,读写位置postion=数据的大小。在缓冲区数据没有读取完全,又需要插入数据时使用。
ByteBuffer buffer = ByteBuffer.allocate(32);
buffer.put(new byte[16]);
buffer.flip();
System.out.println("filp 后 limit:" + buffer.limit());//limit=16
buffer.getInt();//
System.out.println("get int 后postion:" + buffer.position());//postion=4
buffer.compact();
System.out.println("compact 后 postion:" + buffer.position());//postion=12
7
mark(),初始是未定义的,这适合如果调用reset将抛出InvalidMarkException。调用mark()后,将当前position设为mark以便reset时返回。注意,rewind( ), clear( ), and flip( )方法都将丢弃已经创建的mark。调用limit(index),position(index),如果index的值小于当前mark,mark也将被丢弃。
3.字节缓冲区
public static void useByteBuffer(){
ByteBuffer buffer = ByteBuffer.allocate(32);
//buffer.order(ByteOrder.BIG_ENDIAN);
buffer.put((byte)1);
buffer.put(new byte[3]);
buffer.putChar('A');
System.out.println(buffer.position());//char 占2个byte,postion=6
buffer.putFloat(1.222f);//postion=10
buffer.putLong(100L);
System.out.println(buffer.get(0));
System.out.println(buffer.getChar(4));
System.out.println(buffer.getFloat(6));
System.out.println(buffer.getLong(10));;
}
用ByteBuffer存取其它基本类型,需要自己计算位置,位置错了,读取的数据也会出错。
字节顺寻,使用ByteBuffer存取其它基本类型数据,比如char,需要两个字节,所以要考虑字节顺序。默认使用的是大端顺序:ByteOrder.BIG_ENDIAN.
ByteBuffer可以转换成其它(CharBuffer,IntBuffer,FloatBuffer,LongBuffer 等)视图。
转换成新的视图后,共享的空间是从当前读写位置到读写限制的空间。
ByteBuffer buffer = ByteBuffer.allocate(32);
buffer.putInt(1); //postion=4
IntBuffer intBuffer = buffer.asIntBuffer();//共享空间 位置:4-31
intBuffer.put(4);
intBuffer.flip();
System.out.println(intBuffer.get());//4
System.out.println(buffer.getInt());//4