byteBuffer幾個方法含義: java
三者關係:函數
標誌位 | 初始值 | 說明 |
---|---|---|
mark | -1 | 標記位 |
position | 0 | 當前位置 |
limit | 指定的緩衝區容量 | 已寫入有效數據容量 |
capacity | 指定的緩衝區容量 | 緩衝區容量 |
ByteBuffer提供兩種不一樣的構造函數,其本質主要是構建的ByteBuffer類型不一樣,其中一種構造函數參照源代碼:性能
//第一種,分配的是DirectByteBuffer public static ByteBuffer allocateDirect(int capacity) { return new DirectByteBuffer(capacity); } //第二種,分配的是HeapByteBuffer public static ByteBuffer allocate(int capacity) { if (capacity < 0) throw new IllegalArgumentException(); return new HeapByteBuffer(capacity, capacity); }
詳細兩種不一樣類型的Buffer這裏不展開討論,可是大多數狀況下,若是對性能沒有太大要求的話,通常默認使用HeapByteBuffer。當咱們執行初始化操做後: ByteBuffer.allocate(緩衝區大小);
. this
其中初始化的值,分別爲position=0,limit和capacity等於咱們指定的緩衝區大小,mark默認爲-1。網上有一些教程的圖示默認顯示了mark爲起始點,實際上是一種低級錯誤,讓別人誤覺得mark就等於起始位置。spa
顧名思義,put操做就是就是將數據放入緩衝區中,每一次put操做,都會position加上put進去的數據長度.position每加一,表明緩衝區內增長了一個字節的數據,具體put的操做原理以下: code
若是送入的數據大小大於緩衝區剩餘容量,則會拋出異常:java.nio.BufferOverflowException
,雖然可能有實際部分數據被寫入緩衝區,可是flip以後,limit位置仍是最後一次正確寫入緩衝區的位置。教程
Flip,回針(請聯想老式打字機),是讓limit指向當前position的位置,position指向起始位置,此時position=0,進行這一部操做以後,就能夠肯定了當前緩衝區的有效數據。而且爲數據讀取作準備。ip
Get操做,就是按照position當前位置,取出緩衝區的數據,每一次取操做以後,position都會get出的數據長度。一樣,position每加一,表明從緩衝區內讀取到了一個字節的數據,不過數據並不會被刪除,只是單純的讀取操做。若是,get以後,position值大於limit值,則拋出異常:java.nio.BufferUnderflowException
ci
mark,就是標記當前的位置,一旦後續進行reset操做以後,能夠快速地定位到mark的位置。在某一些應用場合中,配合reset,這是一個很是方便的操做函數。get
一旦進行過mark操做以後,後續讀取操做中,若是再執行reset操做,就能夠快速定位到標記位上:
Clear操做很簡單,就是全部標誌位都會被恢復成默認值,包括mark值,可是記住,不是數據,寫入緩衝區的數據仍然保留,若是這時候執行get操做,仍然能夠將數據獲取出來。直觀的話,能夠直接看源代碼:
public final Buffer clear() { position = 0; limit = capacity; mark = -1; return this; }
slice方法的做用,就是作數據分割,將當前的position到limit之間的數據分割出來,返回一個新的ByteBuffer,同時,mark標記重置爲-1。不過這裏注意,分割出來的數據的容量恰好就是數據長度,而不是被分割以前的長度。
有時候,咱們只是想要去掉前面一部分,而保留後面一部分數據,同時保持緩衝區的大小不變呢,這裏提供一種思路,以下:
public void clearPrePositionData(ByteBuffer byteBuffer) { ByteBuffer buffer2 = byteBuffer.slice(); byteBuffer.clear(); if (buffer2.capacity() > 0) { byteBuffer.put(buffer2); } else { byteBuffer.mark(); byteBuffer.reset(); } byteBuffer.flip(); }