第四節 netty前傳-NIO中緩衝buffer-02
上一節中基本上已經介紹過buffer的核心部分,本節介紹buffer的幾種很常用的api
-
獲取Buffer物件,並初始化
要獲取Buffer物件,必須先分配它。 每個Buffer類都有一個allocate()方法來
初始化一個緩衝區,大小為1024byte
ByteBuffer buf = ByteBuffer.allocate(1024);
-
向Buffer物件中寫入資料
一般會有兩種方式向buffer物件中寫入資料,一種是通過Channel 寫入,另外一種是buffer自身的api
使用put方法
第一種:int bytesRead = fileChannel.read(buf);
第二種:buf.put(2);
-
flip()方法
前面已經說過flip() 方法將Buffer從寫入模式切換到讀取模式時。 將limit設定為寫模式的位置,同時會將positon設定回0。
-
從buffer讀取資料
和寫入相似,也有兩種方式。其一是通過channel中讀取buffer中的資料,其二時直接通過buffer自身get方法讀取
//read from buffer into channel.
int bytesWritten = inChannel.write(buf);
//直接讀取
byte aByte = buf.get();
-
rewind()方法
rewind方法將position設定回0,因此可以重讀緩衝區中的所有資料。並且limit保持不變,因此仍然標記可以從緩衝區讀取多少元素(位元組,字元等)。 -
clear() 和compact()
這倆方法上一節也說過了,都是清除buffer中已讀資料,準備開始寫入。不同的是,clear方法會將position標記為0,意味著從頭開始寫入也會覆蓋之前buffer中未讀的資料。compact不同之處在於,它會將未讀的資料移到buffer的開頭,然後會將postion標記為這些未讀的資料之後,這樣寫入資料就不會覆蓋這些未讀的資料。換句話說如果仍然想讀取之前未讀的資料就用compact,否則使用clear方法 -
mark() 和 reset()
一般來說這兩個方法是成對出現,通過呼叫Buffer.mark() 方法會在Buffer中標記當前的位置,下面是 Buffer類中兩個方法的原始碼。 通過呼叫Buffer.reset() 方法將位置重置回標記位置。
/** * Sets this buffer's mark at its position. */ public Buffer mark() { mark = position; return this; } /** * Resets this buffer's position to the previously-marked position. * <p> Invoking this method neither changes nor discards the mark's * value. </p> * @returnThis buffer * @throwsInvalidMarkException *If the mark has not been set */ public Buffer reset() { int m = mark; if (m < 0) throw new InvalidMarkException(); position = m; return this; }
使用場景
buffer.mark();//標記當前的位置
buffer.get() //中間可能讀取一些資料,然後又想從標記位置再次讀取
buffer.reset();//回到標記位置,就可再次讀取
-
最後說一下equals() 和compareTo()方法
比較啷個buffer是否相同,buffer給出以下規定
它們的型別相同(byte,char,int等) 它們在緩衝區中具有相同數量的剩餘位元組,字元等。 所有剩餘的位元組,字元等都相等。
equals僅比較緩衝區的一部分,而不是它內部的每個元素。 實際上,它只是比較緩衝區中的其餘元素。compareTo()方法比較兩個緩衝區的剩餘元素(位元組,字元等)。 在下列情況下,緩衝區被視為“小於”另一個緩衝區:
1、與另一個緩衝區中的對應元素相等的第一個元素小於另一個緩衝區中的元素。 2、 所有元素都相等,但第一個緩衝區在第二個緩衝區之前耗盡了元素(它有更少的元素)。