ByteBuffer與ByteBuf用法比較

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章