[TOC]
一、bytebuffer内部结构
1.1 属性介绍
Bytebuffer有以下重要属性:
- capacity(容量) :缓冲区的容量。通过构造函数赋予,一旦设置,无法更改。
- position(指针) :读写指针,记录数据读写的位置,缓冲区的位置不能为负,并且 不能大于limit 。
- limit(读写限制) :缓冲区的界限。位于limit 后的数据不可读写。缓冲区的限制不能为负,并且 不能大于其容量 。
1.2 结构
- 写模式
当缓冲区刚创建成功时
写模式下,position 是写入位置,limit 等于容量。
下图表示写入了 4 个字节后的状态:
Position移动到第5个字节开始位置
- 读模式
flip动作发生后,position切换为读取位置,limit切换为读取限制
- position重新赋值到开始位置,因为读取数据从开始位置开始读取
- limit被赋值为position写入时的最后位置,作为数据读取的最终位置
读取4个字节后,状态如下图:
- 当position位置与limit位置相同时,数据读取结束。
- 数据未读取完重新切换到写模式时
compact 方法,是把未读完的部分向前压缩,然后切换至写模式
二、ByteBuffer常见方法
-
put()
**描述:**可以将一个数据放入到缓冲区中。
进行该操作后,postition的值会+1,指向下一个可以放入的位置。capacity = limit ,为缓冲区容量的值。
-
flip()
描述 :用来 切换对缓冲区的操作模式 ,由写->读 / 读->写
进行该操作后:
- 如果是写模式->读模式,position = 0 , limit 指向最后一个元素的下一个位置,capacity不变;
- 如果是读模式->写模式,则恢复为put()方法中的值。
-
get()
描述 :该方法会读取缓冲区中的一个值
进行该操作后,position会+1,如果超过了limit则会抛出异常
注意:get(i)方法不会改变position的值
-
rewind()
描述 :该方法 只能在读模式下使用
rewind()方法后,会恢复position、limit和capacity的值,变为进行get()前的值
-
clean()
描述:会将缓冲区中的各个属性恢复为最初的状态,position = 0, capacity = limit
此时缓冲区的数据依然存在 ,处于“被遗忘”状态,下次进行写操作时会覆盖这些数据
-
mark()/reset()
描述 :mark 是在读取时,做一个标记,即使 position 改变,只要调用 reset 就能回到 mark 的位置
mark() :将postion的值保存到mark属性中
reset() :将position的值改为mark中保存的值
注意:rewind 和 flip 都会清除 mark 位置
-
compact()
描述 :compact会把未读完的数据向前压缩,然后切换到写模式
数据前移后,原位置的值并未清零,写时会 覆盖 之前的值
注意:此方法为ByteBuffer的方法,而不是Buffer的方法
clear()和compact()方法对比:
clear只是对position、limit、mark进行重置,而compact在对position进行设置,以及limit、mark进行重置的同时,还涉及到数据在内存中拷贝(会调用arraycopy)。**所以compact比clear更耗性能。**但compact能保存你未读取的数据,将新数据追加到为读取的数据之后;而clear则不行,若你调用了clear,则未读取的数据就无法再读取到了
需要根据情况来判断使用哪种方法进行模式切换
附参考文章:
《黑马程序员Netty教程》