一文解讀java.nio.ByteBuffer
java.nio.ByteBuffer 是一個(gè)可以進(jìn)行 緩沖區(qū)分配 、 讀取 和 寫入 的緩沖區(qū),其 持有一個(gè)字節(jié)數(shù)組
并通過4個(gè)屬性:
capacitylimitpositionmark
來管理緩沖區(qū),進(jìn)行字節(jié)級(jí)別讀取和數(shù)據(jù)寫入。
基于此,ByteBuffer常被用來處理網(wǎng)絡(luò)協(xié)議和I/O操作。
一、使用舉例
以下為ByteBuffer的使用舉例:
- 可以使用
put()方法將數(shù)據(jù)寫入緩沖區(qū); - 可以使用
flip()方法切換緩沖區(qū)為讀取模式; - 可以使用
rewind()方法倒回緩沖區(qū)的初始位置; - 可以使用
get()方法讀取緩沖區(qū)中的數(shù)據(jù); - 可以使用
clear()方法清空緩沖區(qū),以便再次寫入數(shù)據(jù)。
import java.nio.ByteBuffer;
public class JavaTest {
public static void main(String[] args)
{
System.out.println("~~~~~~~~ put(byte b) ~~~~~~~~");
// 分配一個(gè)5字節(jié)的buffer
ByteBuffer byteBuffer = ByteBuffer.allocate(5);
// 向buffer中添加兩個(gè)字節(jié)的數(shù)據(jù),空余3個(gè)字節(jié)數(shù)據(jù)
byteBuffer.put((byte)10);
byteBuffer.put((byte)20);
// 輸出整個(gè)字節(jié)數(shù)組
printByteBuffer(byteBuffer);
System.out.println("~~~~~~~~ flip() ~~~~~~~~");
// 轉(zhuǎn)為讀模式
byteBuffer.flip();
// 輸出整個(gè)字節(jié)數(shù)組
printByteBuffer(byteBuffer);
System.out.println("~~~~~~~~ get() ~~~~~~~~");
// 讀取當(dāng)前 position
System.out.println(byteBuffer.get());
// 輸出整個(gè)字節(jié)數(shù)組
printByteBuffer(byteBuffer);
System.out.println("~~~~~~~~ rewind() ~~~~~~~~");
// 倒回緩沖區(qū)的初始位置
byteBuffer.rewind();
printByteBuffer(byteBuffer);
System.out.println("~~~~~~~~ get(byte[] dst, int offset, int length) ~~~~~~~~");
// 將buffer中數(shù)據(jù)寫入到dstBytes中
byte[] dstBytes = new byte[2];
byteBuffer.get(dstBytes, 0, dstBytes.length);
printByteBuffer(byteBuffer);
}
public static void printByteBuffer(ByteBuffer byteBuffer) {
byte[] bytes = byteBuffer.array();
int position = byteBuffer.position();
int limit = byteBuffer.limit();
int remining = byteBuffer.remaining();
System.out.println("byteBuffer: "
+ Arrays.toString(bytes)
+ "\nPosition: " + position
+ " Limit: " + limit
+ " Remining: " + remining);
}
}控制臺(tái)輸出如下:
~~~~~~~~ put(byte b) ~~~~~~~~
byteBuffer: [10, 20, 0, 0, 0]
Position: 2 Limit: 5 Remining: 3
~~~~~~~~ flip() ~~~~~~~~
byteBuffer: [10, 20, 0, 0, 0]
Position: 0 Limit: 2 Remining: 2
~~~~~~~~ get() ~~~~~~~~
10
byteBuffer: [10, 20, 0, 0, 0]
Position: 1 Limit: 2 Remining: 1
~~~~~~~~ rewind() ~~~~~~~~
byteBuffer: [10, 20, 0, 0, 0]
Position: 0 Limit: 2 Remining: 2
~~~~~~~~ get(byte[] dst, int offset, int length) ~~~~~~~~
byteBuffer: [10, 20, 0, 0, 0]
Position: 2 Limit: 2 Remining: 0
二、原理簡析
前邊說過 ByteBuffer持有一個(gè)字節(jié)數(shù)組
并通過4個(gè)屬性:
capacitylimitpositionmark來管理緩沖區(qū)
這4個(gè)屬性遵循
mark <= position <= limit <= capacity ???????
下表格是對(duì)著4個(gè)屬性的解釋:
| 屬性 | 描述 |
|---|---|
| Capacity | 容量,即可以容納的最大數(shù)據(jù)量 |
| Limit | 緩沖區(qū)的當(dāng)前終點(diǎn),不能對(duì)緩沖區(qū)超過極限的位置進(jìn)行讀寫操作 |
| Position | 下一個(gè)要被讀或?qū)懙脑氐乃饕?/td> |
| Mark | 標(biāo)記??烧{(diào)用mark()設(shè)置標(biāo)記(mark=position),然后調(diào)用reset()讓position恢復(fù)到標(biāo)記的位置 |
初始化,各控制屬性狀態(tài):
例如調(diào)用
ByteBuffer byteBuffer = ByteBuffer.allocate(5);
進(jìn)行ByteBuffer存儲(chǔ)空間分配,
各屬性見下圖所示:

寫入數(shù)據(jù)后,各控制控制屬性狀態(tài):
例如調(diào)用
byteBuffer.put((byte)'a')
寫入數(shù)據(jù)后,
各屬性見下圖所示:

讀取數(shù)據(jù)后,各控制控制屬性狀態(tài):
例如調(diào)用
byteBuffer.get()
讀取4個(gè)字節(jié)后,
各屬性見下圖所示:

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
nacos中的配置使用@Value注解獲取不到值的原因及解決方案
這篇文章主要介紹了nacos中的配置使用@Value注解獲取不到值的原因分析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03
一文帶你學(xué)會(huì)Java網(wǎng)絡(luò)編程
網(wǎng)絡(luò)編程是指編寫運(yùn)行在多個(gè)設(shè)備(計(jì)算機(jī))的程序,這些設(shè)備都通過網(wǎng)絡(luò)連接起來。這篇文章將帶大家深入了解一下Java的網(wǎng)絡(luò)編程,需要的可以了解一下2022-08-08
基于java+springboot+mybatis+laiyu實(shí)現(xiàn)學(xué)科競賽管理系統(tǒng)
這篇文章主要介紹了基于java+springboot+mybatis+laiyu實(shí)現(xiàn)的學(xué)科競賽管理系統(tǒng),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09

