一、ByteBuffer实现原理
对于ByteBuffer,其主要有五个属性:mark,position,limit,capacity和array。
- mark:记录了当前所标记的索引下标;
- position:对于写入模式,表示当前可写入数据的下标,对于读取模式,表示接下来可以读取的数据的下标;
- limit:对于写入模式,表示当前可以写入的数组大小,默认为数组的最大长度,对于读取模式,表示当前最多可以读取的数据的位置下标;
- capacity:表示当前数组的容量大小;
- array:保存了当前写入的数据。
// Invariants: mark <= position <= limit <= capacity
这几个数据中,除了array是用于保存数据的以外,这里最终的主要position,limit和capacity三个属性,因为对于写入和读取模式,这三个属性的表示的含义大不一样。
1.写入模式
只要记住position到limit之间是可读、可写的就行(之后就切换到读或者写模式就知道他们的具体值了)
如下图所示为初始状态和写入3个字节之后position,limit和capacity三个属性的状态:
在写入模式下,limit指向的始终是当前可最多写入的数组索引下标,position指向的则是下一个可以写入的数据的索引位置,而capacity则始终不会变化,即为数组大小。
2.读取模式
假设我们按照上述方式在初始长度为6的ByteBuffer中写入了三个字节的数据,此时我们将模式切换为读取模式,那么这里的position,limit和capacity则变为如下形式:
可以看到,当切换为读取模式之后,limit则指向了最后一个可读取数据的下一个位置,表示最多可读取的数据;position则指向了数组的初始位置,表示下一个可读取的数据的位置;capacity还是表示数组的最大容量。这里当我们一个一个读取数据的时候,position就会依次往下切换,当position与limit重合时,就表示当前ByteBuffer中已没有可读取的数据了。
读写切换的时候要记得调用flip()方法;
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
/*
* Flips this buffer. The limit is set to the current position and then
* the position is set to zero. If the mark is defined then it is
* discarded.
*/
二、Bytebuf实现原理
Bytebuf进行了改进,它维持一个rederINdex索引,一个writerIndex索引
//api里面Bytebuf工作原理模型图
+-------------------+------------------+------------------+
* | discardable bytes | readable bytes | writable bytes |
* +-------------------+------------------+------------------+
* | | | |
* 0 <= readerIndex <= writerIndex <= capacity
*
*
* AFTER clear()
*
* +---------------------------------------------------------+
* | writable bytes (got more space) |
* +---------------------------------------------------------+
* | |
* 0 = readerIndex = writerIndex <= capacity
*
初始位置:
readerIndex 代表当前读取的位置,writerIndex 代表下一个可以写入的位置,写入一部分数据后,writerIndex 往右移动,而 readerIndex 和 writeIndex 之间的数据就变为可读的了
如果原先写入了 N 个长度的数据,接下来读取 M (M < N)个长度的数据,那么读取后 ByteBuf 就变成下面的样子
我们不再需要BytrBuffer的的 flip 方法那样了,只需要关注 readerIndex 与 writerIndex就可以实现读写。
参考:https://juejin.im/post/5c468f7be51d45524976275d
https://zhuanlan.zhihu.com/p/56876443
https://www.cnblogs.com/superfj/p/9242968.html