nio學習01 緩衝區

2021-09-29 17:46:42 字數 4526 閱讀 4385

緩衝區是包在乙個物件內的基本資料元素陣列。buffer類似相比乙個簡單的陣列優點是它將關於資料的資料內容和資訊包含在乙個單一的物件中。buffer類似及它專有的子類定義了乙個用於處理緩衝區的api。

他的本質是一塊可以寫入資料,然後可以從中讀取資料的記憶體。這塊記憶體被包裝成nio物件,並提供了一組方法,用來方便訪問這塊記憶體

jdk中的buffer抽象類如下圖:

根據資料型別不同(boolean除外),提供了相應型別的緩衝區:

bytebuffer

charbuffer

shortbuffer

integerbuffer

longbuffer

floatbuffer

doublebuffer

上面緩衝區的管理方式幾乎一致,通過allocate()獲取緩衝區

兩個核心方法:

put()存入資料到快取區

get():獲取快取區中的資料

mark,position,limit,capacity

capacity(容量):緩衝區能夠容納的資料的最大數量。這一容量在緩衝區建立時被設定,並且永遠不能被改變。

limit(上界):緩衝區的第乙個不能被讀或者被寫的元素。或者說,緩衝區中現存元素的計數。

position(位置):下乙個要被讀或者寫的元素。位置會自動由相應的get()和put()方法函式更新。

mark(標記):乙個備忘位置。呼叫mark()來設定mark= position。呼叫reset()設定position=mark。標記在設定前是未定義的。

四個屬性之間的關係

0 <= mark <= position <= limit <= capacity
下面的圖可以看一下:

非直接緩衝區:通過allocate()方法分配緩衝區,將緩衝區建立在jvm的記憶體中。

非直接緩衝區:通過allocatedirect()方法分配直接緩衝區,將緩衝區建立在物理記憶體中。可以提高效率。

現在為寫的模式

1.分配乙個指定大小的緩衝區

string str = "abcde";

//1. 分配乙個指定大小的緩衝區

bytebuffer buf = bytebuffer.allocate(1024);

system.out.println("-----------------allocate()----------------");

system.out.println(buf.position());

system.out.println(buf.limit());

system.out.println(buf.capacity());

結果如下:

-----------------allocate()----------------

01024

1024

結果分析:

位置被設定為0,而且容量和上界被設定為1024,剛好經過緩衝區能夠容納的最後乙個位元組。

初始值以及初始位置

2.利用put()存入資料到緩衝區中

buf.put(str.getbytes());

system.out.println("-----------------put()----------------");

system.out.println(buf.position());

system.out.println(buf.limit());

system.out.println(buf.capacity());

結果如下:

-----------------put()----------------

51024

1024

3.切換讀取資料模式

buf.flip();

system.out.println("-----------------flip()----------------");

system.out.println(buf.position());

system.out.println(buf.limit());

system.out.println(buf.capacity());

結果如下:

-----------------flip()----------------05

1024

呼叫flip()方法之後切換為讀的模式position變為0,position新向前移動到下乙個可讀的位置。

切換到讀的模式之後limit表示你最多能讀多少資料,這裡能讀到的資料最多是5。

4.利用 get() 讀取緩衝區中的資料

system.out.println("-----------------get()----------------");

byte dst = new byte[buf.limit()];

buf.get(dst);

system.out.println(new string(dst, 0, dst.length));

system.out.println(buf.position());

system.out.println(buf.limit());

system.out.println(buf.capacity());

結果如下:

-----------------get()----------------

abcde55

1024

結果分析:

在呼叫了get方法以後posiotion的值變成了5,也就是limit的值。理解為從最開始開始讀取資料,讀到了最後乙個字元。

現在我讀到了資料的最後乙個字元,現在想要再返回來讀取怎麼處理?下面引出他的rewind()方法

表示可重複讀

5.rewind() : 可重複讀

buf.rewind();

system.out.println("-----------------rewind()----------------");

system.out.println(buf.position());

system.out.println(buf.limit());

system.out.println(buf.capacity());

結果如下:

-----------------rewind()----------------05

1024

結果分析:

資料又回到了最開始的資料位置。position變成了0。

rewind方法讀寫模式下都可以使用,它單純的將當前位置置零,同時取消mark標記

6. clear() : 清空緩衝區. 但是緩衝區中的資料依然存在,但是處於「被遺忘」狀態

buf.clear();

system.out.println("-----------------clear()----------------");

system.out.println(buf.position());

system.out.println(buf.limit());

system.out.println(buf.capacity());

system.out.println((char)buf.get());

結果如下:

-----------------clear()----------------

01024

1024

a

和clear類似的還有乙個方法,compact()方法

一旦讀完buffer中的資料,需要讓buffer準備好再次被寫入。可以通過clear和compact方法來完成。

clear方法  position將被設定成0,limit被設定capacity。換句話說,buffer被清空了。buffer中的資料並未清除,只是這些告訴我們可以從**開始往buffer裡面寫資料。

如果buffer中有未讀玩的資料,呼叫clear方法,資料將被遺忘,意味著不再有任何標記會告訴你哪些資料被讀過,哪些還沒有。

如果buffer中仍有未讀的資料,且後續還需要這些資料,但是此時想要先寫入這些資料,那麼呼叫compact方法。

compact方法將所有未讀的資料拷貝到buffer起始處。然後將position設定到最後乙個未讀元素的後面。limit屬性依然像clear方法一樣,設定成capacity。現在buffer準備好寫資料了,但是不會覆蓋未讀的資料。

IO模型 NIO緩衝區

緩衝區 buffer 緩衝區本質上是一塊可以寫入資料,然後可以從中讀取資料的記憶體 底層是陣列 這塊記憶體被包裝成nio buffer物件,並提供了一組方法,用來方便的訪問該塊記憶體。理解buffer的工作原理,需要熟悉它的三個屬性 capacity 容量,即可以容納的最大資料量 在緩衝區建立時被設...

NIO 筆記二 緩衝區

乙個 buffer 物件是固定數量的資料的容器。其作用是乙個儲存器,或者分段運輸區,在這裡資料可被儲存並在之後用於檢索。對於每個非布林原始資料型別都有乙個緩衝區類。儘管緩衝區作用於它們儲存的原始資料型別,但緩衝區十分傾向於處理位元組。非位元組緩衝區可以在後台執行從位元組或到位元組的轉換,這取決於緩衝...

NIO學習筆記之緩衝區Buffer

buffer有四個屬性 1 capacit 容量 2 limit 上界 3 position 位置 4 mark 標記 絕對儲存不會影響緩衝區的位置屬性 存和取的方法 public abstract byte get public abstract byte get int index public...