一、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