1.抽象类 ByteBuffer extends Buffer,Buffer也是抽象类,是一个缓冲定义,定义了如下缓冲属性:
- mark:标记position,只有调用mark()方法时才操作mark,而调用flip()、rewind()、clear()都重置mark。调用reset()方法前,必须调用mark(),否则抛出异常。
- position:记录操作的位置,position<limit且 limit-position>=接下来的读(写)所占用的字节数
- limit:缓冲数组可以操作的界限,插入时(初始化时):limit=capacity。改变limit的方法:flip()——>limit=position clear()——>limit=capacity、
- capacity:初始化时指定数组的大小
2.常用方法解析:
- flip():最后一个操作的position作为limit,position重置,mark重置,之后的操作中,limit作为界限。 作用:建议只用在且必须用 写完之后,准备好读。设置读的界限。写完之后,capacity没用完,如果不调用该方法设置读的界限,当读到剩下没用的空间时,可能读到上一次操作留下的数据。
注意:当上一次操作没到limit界限,调用flip()方法,将导致缓冲数组的limit界限之后的空间和数据不可操作
public Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
- clear():重置缓冲数组:position=0; limit=capacity;mark=-1;
public Buffer clear() { position = 0; limit = capacity; mark = -1; return this; }
- reset():将postion移动到mark记录的位置,从mark开始接下来的操作,mark<0将抛出异常。那mark什么时候才不等于 -1呢?答案是:只有调用mark()方法时,才能改变mark,且mark=position(当前位置)。
- rewind():和flip()的区别是不改变limit的位置。作用:重复从0开始读(写)
- 还可以手动设置position和limit : position(int pos) limit(int limit)
- 获取缓冲数组的状态信息的方法:剩下的字节:remaining(){ return limit-position;} 容量:capacity() 界限:limit() 位置:position()
- wrap(byte[] bytes ,int offset,int length):返回byteBuffer
3.读写细节,下标的变化:
读和写都会调用nextPutIndex方法来判断下一个开始读(开始写)的位置,如何读写八大数据类型呢?nb:对应数据类型所占 的字节数。
步骤:(其他数据类型都是同样的道理)
- 如果剩下的可操作空间(limit-position)小于nb抛出异常
- p=position:从p位置开始读
- 读nb个字节,position+=nb
final int nextPutIndex(int nb) { // package-private
if (limit - position < nb)
throw new BufferOverflowException();
int p = position;
position += nb;
return p;
}
4.ByteBuffer的子类:HeapByteBuffer 、DirectByteBuffer,他们的区别看这篇博客:https://blog.youkuaiyun.com/mweibiao/article/details/77196257