1. ByteBuffer 的設計是抽象類#
主要的實現類有:
HeapByteBuffer 堆 ByteBuffer 用的是 JVM 內的堆內存 --> 讀寫操作效率低 會受到 GC 的影響
2. MapperByteBuffer(抽象類 ,它還有個實現類叫 DirectByBuffer) 使用 OS 內存 ---> 讀寫操作效率高 不受 GC 影響。但是如果不主動析構的話,容易造成內陸泄漏
獲取方式#
Bytebuffer.allocate (10); // 一旦分配空間,不可以動態調整
encode()
核心結構#
ByteBuffer 是一個類似數組的結構,整個結構中包含三個主要的狀態
- Capacity
buffer 的容量,類似於數組的 size- Position
buffer 當前緩存的下標,在讀取操作時記錄讀到了那個位置,在寫操作時記錄寫到了那個位置。從 0 開始,每讀取一次,下標 + 1- Limit
讀寫限制,在讀操作時,設置了你能讀多少字節的數據,在寫操作時,設置了你
還能寫多少字節的數據
所謂的讀寫模式,本質上就是這幾個狀態的變化。主要有 Position 和 Limit 聯合決定了 Buffer 的讀寫數據區域。
** 下面用圖和代碼的形式來表達 capacity、limit 、position 的狀態改變 **
@Test
public void test1(){
ByteBuffer buffer = ByteBuffer.allocate(10);
// 新創建的buffer 的狀態
System.out.println("buffer.capacity() = " + buffer.capacity()); // 10
System.out.println("buffer.position() = " + buffer.position()); // 0
System.out.println("buffer.limit() = " + buffer.limit()); // 10
}
@Test
public void test2(){
ByteBuffer buffer = ByteBuffer.allocate(10);
// 存幾個數據,然後再看狀態
buffer.put(new byte[]{'a','b','c','d'});
System.out.println("buffer.capacity() = " + buffer.capacity()); // 10
System.out.println("buffer.position() = " + buffer.position()); // 4
System.out.println("buffer.limit() = " + buffer.limit()); // 10
}
@Test
public void test3(){
ByteBuffer buffer = ByteBuffer.allocate(10);
// 存幾個數據
buffer.put(new byte[]{'a','b','c','d'});
// 切換為讀模式,再看狀態
buffer.flip();
System.out.println("buffer.capacity() = " + buffer.capacity()); // 10
System.out.println("buffer.position() = " + buffer.position()); // 0
System.out.println("buffer.limit() = " + buffer.limit()); // 4
}
@Test
public void test4(){
ByteBuffer buffer = ByteBuffer.allocate(10);
// 存幾個數據
buffer.put(new byte[]{'a','b','c','d'});
// 切換為寫模式,再看狀態
buffer.clear();
System.out.println("buffer.capacity() = " + buffer.capacity()); // 10
System.out.println("buffer.position() = " + buffer.position()); // 0
System.out.println("buffer.limit() = " + buffer.limit()); // 10
}
@Test
public void test5(){
ByteBuffer buffer = ByteBuffer.allocate(10);
// 存幾個數據
buffer.put(new byte[]{'a','b','c','d'});
// 讀取2個數據
buffer.flip();
byte b = buffer.get();
byte b2 = buffer.get();
System.out.println("buffer.capacity() = " + buffer.capacity()); // 10
System.out.println("buffer.position() = " + buffer.position()); // 2
System.out.println("buffer.limit() = " + buffer.limit()); // 4
// 用compact來切換寫模式,再看狀態
buffer.compact();
System.out.println("buffer.capacity() = " + buffer.capacity()); // 10
System.out.println("buffer.position() = " + buffer.position()); // 2
System.out.println("buffer.limit() = " + buffer.limit()); // 10
/* 結果
* buffer.capacity() = 10
buffer.position() = 2
buffer.limit() = 4
buffer.capacity() = 10
buffer.position() = 2
buffer.limit() = 10
* */
}
最後總結一下#
寫入 Buffer 數據之前要設置寫模式
- 寫模式
- 新創建的 Buffer 自動是寫模式
- 調用了 clear,compact 方法
讀取 Buffer 數據之前要設置讀模式
2. 讀模式
- 調用 flip 方法