NIO學習筆記之緩衝區Buffer

2021-07-12 06:32:58 字數 4989 閱讀 3242

buffer有四個屬性:

1、capacit(容量)

2、limit(上界)

3、position(位置)

4、mark(標記)

*:絕對儲存不會影響緩衝區的位置屬性

存和取的方法:

public

abstract

byte

get( );

public

abstract

byte

get (int index);

public

abstract bytebuffer put (byte b);

public

abstract bytebuffer put (int index, byte b);

get和put可以是相對的或者是絕對的。在前面的程式列表中,相對方案是不帶有索引引數的函式。當相對函式被呼叫時,位置在返回時前進一。如果位置前進過多,相對運算就會丟擲異常。對於put(),如果運算會導致位置超出上界,就會丟擲bufferoverflowexception異常。對於get(),如果位置不小於上界,就會丟擲bufferunderflowexception異常。絕對訪問不會影響緩衝區的位置屬性,但是如果您所提供的索引超出範圍(負數或不小於上界),也將丟擲indexoutofbound***ception異常。

翻**

buffer.flip()

這是乙個封裝好了的函式,它的功能與下面函式執行的功能是等效的

buffer.limit(buffer.position()).position(0)

這樣做的目的是:當你對乙個緩衝區裝載完畢時,你需要改變它的位置狀態讓它準備好被取出資料。所以我們把它的位置定位為0,上界定位為當前載入到的位置。

書本上的解釋:

flip()函式將乙個能夠繼續新增資料元素的填充狀態的緩衝區翻轉成乙個準備讀出元素的釋放狀態。在翻轉之後,圖2.4的緩衝區會變成下圖中的樣子。

釋放資料

在對資料釋放前,一定要確保對緩衝區進行了一次翻轉操作(並且只能有一次)

使用hasremaining()函式可以判斷是否達到緩衝區的上界。

for (int i = 0; buffer.hasremaining( ), i++)
我們也可以自己自己使用remaining()函式獲得可讀取的資料數自行迴圈

int

count = buffer.remaining( );

for (int i = 0; i < count, i++)

如果您對緩衝區有專門的控制,這種方法會更高效,因為上界不會在每次迴圈重複時都被檢查(這要求呼叫乙個buffer樣例程式)。上文中的第乙個例子允許多執行緒同時從緩衝區釋放元素。

*:緩衝區的訪問不是執行緒安全的。使用多執行緒一定要進行同步

使用compact()函式可以壓縮未讀的緩衝區

以下是jdk api中的解釋:

public abstract charbuffer compact()壓縮此緩衝區(可選操作)。

將緩衝區當前位置和界限之間的字元(如果有)複製到緩衝區的開始處。即將索引 p = position() 處的字元複製到索引 0 處,將索引 p + 1 處的字元複製到索引 1 處,依此類推,直到將索引 limit() - 1 處的字元複製到索引 n = limit() - 1 - p 處。然後將緩衝區的位置設定為 n+1,並將其界限設定為其容量。如果已定義了標記,則丟棄它。

將緩衝區的位置設定為複製的字元數,而不是零,以便呼叫此方法後可以緊接著呼叫另乙個相對 put 方法。

書上解釋:呼叫compact()的作用是丟棄已經釋放的資料,保留未釋放的資料,並使緩衝區對重新填充容量準備就緒。

如果您想在壓縮後釋放資料,緩衝區會像之前所討論的那樣需要被翻轉。無論您之後是否要向緩衝區中新增新的資料,這一點都是必要的。

標記

這本章節的開頭,我們已經涉及了緩衝區四種屬性中的三種。第四種,標記,使緩衝區能夠記住乙個位置並在之後將其返回。緩衝區的標記在mark( )函式被呼叫之前是未定義的,呼叫時標記被設為當前位置的值。reset( )函式將位置設為當前的標記值。如果標記值未定義,呼叫reset( )將導致invalidmarkexception異常。一些緩衝區函式會拋棄已經設定的標記(rewind( ),clear( ),以及flip( )總是拋棄標記)。如果新設定的值比當前的標記小,呼叫limit( )或position( )帶有索引引數的版本會拋棄標記。

緩衝區的比較

緩衝區之前可以使用equals()函式或compareto()函式進行比較。

如果兩個緩衝區中剩餘的內容相同,那麼equals()函式會返回true。

兩個緩衝區相等的充要條件:

批量移動

public charbuffer get (char  dst) 

public charbuffer get (char dst, int offset, int length) public

final charbuffer put (char src)

public charbuffer put (char src, int offset, int length) public charbuffer put (charbuffer src)

public

final charbuffer put (string src)

public charbuffer put (string src, int start, int end)

批量傳輸的大小總是固定的。省略長度意味著整個陣列會被填滿。

如果緩衝區的長度沒有指定陣列的長度長,那麼整個傳輸都會失敗,並且會丟擲乙個bufferunderflowexception異常

以charbuffer為例。

1、使用靜態函式allocate建立指定大小的緩衝區:

charbuffer charbuffer =charbuffer.allocate (100);
2、使用靜態函式warp將陣列轉化為charbuffer,注意陣列的型別必須和buffer匹配

char  myarray = new

char [100];

charbuffer charbuffer = charbuffer.wrap (myarray);

warp還可加入兩個引數分別作為position和limit

使用上兩種方式建立的緩衝區通常都是間接的,間接的緩衝區使用備份陣列,可以使用hasarray函式判斷緩衝區是否有乙個可訪問的備份陣列,使用array函式可以得到備份陣列,任何對備份陣列的更改都會對映到緩衝區

以charbuffer為例

api中提供了以下方法:

public

abstract charbuffer duplicate( );

public

abstract charbuffer asreadonlybuffer( );

public

abstract charbuffer slice( );

duplicate函式建立了乙個與原始緩衝區相似的緩衝區,每個緩衝區有自己的位置資訊,但對緩衝區的修改都會對映到同乙個底層陣列上。

slice建立乙個分割緩衝區:分割緩衝區與複製相似,但slice()建立乙個從原始緩衝區的當前位置開始的新緩衝區,並且其容量是原始緩衝區的剩餘元素數量(limit-position)。這個新緩衝區與原始緩衝區共享一段資料元素子串行。分割出來的緩衝區也會繼承唯讀和直接屬性。

關於位元組儲存順序:

只有bytebuffer的字元順序設定可以隨時通過呼叫以byteorder.big_endian或byteorder.littl_endian為引數的order()函式來改變。

如果乙個緩衝區被建立為乙個bytebuffer物件的檢視(參見2.4.3節),那麼order()返回的數值就是檢視被建立時其建立源頭的bytebuffer的位元組順序設定。檢視的位元組順序設定在建立後不能被改變,而且如果原始的位元組緩衝區的位元組順序在之後被改變,它也不會受到影響。。

直接緩衝區:

呼叫bytebuffer.allocatedirect()函式產生

它直接與jvm低底層的io互動,效率最高

位元組緩衝區可以建立檢視:

public

abstract charbuffer ascharbuffer(); public

abstract shortbuffer asshortbuffer(); public

abstract intbuffer asintbuffer(); public

abstract longbuffer aslongbuffer(); public

abstract floatbuffer asfloatbuffer(); public

abstract doublebuffer asdoublebuffer();

bytebuffer類提供了乙個不太重要的機制來以多位元組資料型別的形式訪問byte資料組。bytebuffer類為每一種原始資料型別提供了訪問的和轉化的方法:

public

abstract

class

bytebuffer

extends

buffer

implements

comparable

NIO 筆記二 緩衝區

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

nio學習01 緩衝區

緩衝區是包在乙個物件內的基本資料元素陣列。buffer類似相比乙個簡單的陣列優點是它將關於資料的資料內容和資訊包含在乙個單一的物件中。buffer類似及它專有的子類定義了乙個用於處理緩衝區的api。他的本質是一塊可以寫入資料,然後可以從中讀取資料的記憶體。這塊記憶體被包裝成nio物件,並提供了一組方...

IO模型 NIO緩衝區

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