Netty 中數據是以ByteBuf爲單位進行交互的。指針
那麼分析一下ByteBuf結構code
ByteBuf結構blog
1 ByteBuf是一個字節容器,結構分爲三個部分,第一部分是已丟棄字節,這部分數據是無效的,第二部分是可讀字節,這部分數據是ByteBuf的主體數據,從 ByteBuf 裏面讀取的數據都來自這一部分;最後一部分的數據是可寫字節,全部寫到 ByteBuf 的數據都會寫到這一段。最後一部分虛線表示的是該 ByteBuf 最多還能擴容多少容量
2 上面3段內容有兩個指針劃分出來的,從左到右,依次是讀指針(readerIndex)、寫指針(writerIndex),其中變量capacity是ByteBuf的總容量。
3 從 ByteBuf 中每讀取一個字節,readerIndex 自增1,ByteBuf 裏面總共有 writerIndex-readerIndex 個字節可讀, 由此能夠推論出當 readerIndex 與 writerIndex 相等的時候,ByteBuf 不可讀
4 寫數據是從 writerIndex 指向的部分開始寫,每寫一個字節,writerIndex 自增1,直到增到 capacity,這個時候,表示 ByteBuf 已經不可寫了
5 ByteBuf 裏面其實還有一個參數 maxCapacity,當向 ByteBuf 寫數據的時候,若是容量不足,那麼這個時候能夠進行擴容,直到 capacity 擴容到 maxCapacity,超過 maxCapacity 就會報錯內存
容量APIci
capacity()
表示ByteBuf的總容量。即 ByteBuf 底層佔用了多少字節的內存(包括丟棄的字節、可讀字節、可寫字節),不一樣的底層實現機制有不一樣的計算方式。it
readableBytes() 與 isReadable()
readableBytes() 表示 ByteBuf 當前可讀的字節數,它的值等於 writerIndex-readerIndex,若是二者相等,則不可讀,isReadable() 方法返回 falsetable
writableBytes()、 isWritable() 與 maxWritableBytes()
其中writableBytes()表示ByteBuf可寫的字節,它等於capacity-writerIndex,若是二者相等則表示不能向其中寫數據了,isWritable()返回false。則不能向其中添加數據了,
可是Netty有自動擴容機制,直到擴容到底層的內存大小爲 maxCapacity,而 maxWritableBytes() 就表示可寫的最大字節數,它的值等於 maxCapacity-writerIndex容器
讀寫指針相關的 API變量
readerIndex() 與 readerIndex(int)
前者表示返回當前的讀指針 readerIndex, 後者表示設置讀指針方法
writeIndex() 與 writeIndex(int)
前者表示返回當前的寫指針 writerIndex, 後者表示設置寫指針
markReaderIndex() 與 resetReaderIndex()
前者表示把當前的讀指針保存起來,後者表示把當前的讀指針恢復到以前保存的值,下面兩段代碼是等價的
// 代碼片斷1 int readerIndex = buffer.readerIndex(); // .. 其餘操做 buffer.readerIndex(readerIndex); // 代碼片斷二 buffer.markReaderIndex(); // .. 其餘操做 buffer.resetReaderIndex();
但願你們多多使用代碼片斷二這種方式,不須要本身定義變量,不管 buffer 看成參數傳遞到哪裏,調用 resetReaderIndex() 均可以恢復到以前的狀態,在解析自定義協議的數據包的時候很是常見,推薦你們使用這一對 API