在 Java NIO(New I/O)體系中,Buffer(緩衝區) 是核心組件之一,它扮演著「中轉站」的角色:數據在通道與緩衝區之間移動,避免頻繁的系統調用,大幅提升 I/O 效能。若無緩衝區,數據將逐字節搬運,極大消耗 CPU 與記憶體資源。
Buffer 為抽象基類,派生出八種基本類型緩衝區:
ByteBuffer(最常用,支援直接記憶體)CharBuffer、ShortBuffer、IntBuffer、LongBufferFloatBuffer、DoubleBuffer所有 Buffer 內部以陣列存儲數據,可透過 array() 取得底層陣列,但需先用 hasArray() 判斷是否可訪問。以下兩種情況無法獲取陣列:
透過 ByteBuffer.allocateDirect(capacity) 分配,記憶體位於 Java 堆外(Native Heap),減輕 GC 壓力、避免堆內存不足。對應地,allocate(capacity) 建立堆緩衝區,wrap(array) 則包裝現有陣列(必在堆上)。可用 isDirect() 判別類型。
調用 asReadOnlyBuffer() 建立,與原緩衝區共享底層陣列,但禁止寫入操作(put() 會拋異常)。同樣無法獲取陣列引用,isReadOnly() 可檢測。
Buffer 操作由三個關鍵指標控制:
position()/position(int)limit()/limit(int)capacity()剩餘可操作元素數 = limit - position,亦可用 remaining();hasRemaining() 判斷是否可繼續操作。若 position 與底層陣列起始處有偏移,arrayOffset() 返回偏移量。
| 方法 | 作用 | position | limit |
|---|---|---|---|
clear() | 準備寫入:清空所有數據 | 0 | capacity |
flip() | 寫→讀:鎖定已寫數據範圍 | 0 | 原 position |
rewind() | 重讀/重寫:position 歸零 | 0 | 不變 |
compact() | 保留未讀數據,移至頭部 | remaining | capacity |
mark()/reset() | 標記/恢復 position | 回檔位 | 不變 |
duplicate() 創建共享數據的副本(屬性獨立);slice() 從當前 position 切片至 limit,同樣共享數據。
多字節類型(如 int 佔 4 字節)存儲順序由 order(ByteOrder) 設定:
ByteOrder.BIG_ENDIAN:高位在前(網絡序)ByteOrder.LITTLE_ENDIAN:低位在前(x86 預設)ByteOrder.nativeOrder() 獲取平台原生字節序,跨平台通訊時務必顯式指定。
flip() 切換讀寫模式,避免數據截斷或重複讀取allocateDirect,避免頻繁擴容掌握 Buffer 核心機制,是編寫高效能 NIO 程式的基石。