mina IoBuffer 常用方法


Limit(int)

如果position>limit, position = limit,如果mark>limit, 重置mark

Mark()

取當前的position的快照標記mark

Reset()

恢復position到先前標記的mark

Clear()

limit=capacity , position=0,重置mark,但是不清空數據,為了從頭開始put做准備,其實就是清空數據,因為你put就覆蓋了原來的數據

Rewind()

position=0,重置mark,一系列寫操作后,為了從頭開始get做准備,和clear()有用途上的區別,他大部分是用來從頭開始讀取,而clear是大部分用來重頭開始填充,就是清理的意思

Flip()

limit=position , position=0,重置mask,為了將buf寫出做好准備,一般是結束buf操作,將buf寫入輸出流時調用,這個必須要調用,否則極有可能position!=limit,導致position后面沒有數據,每次寫入數據到輸出流時,必須確保position=limit。

Remaining()

返回limit-position,返回緩沖器中的剩余字節

Wrap(byte[])

組裝到新的buffer,capacity=limit=byte[].length,position=0 重置mark

Slice()

分割緩沖器,將remaining的空間形成一個新的buffer,新的position=0,limit=capacity=remaining,重置mark,和主緩沖區內容共享,其它都獨立

Duplicate()

緩沖區,內容共享,其它都獨立

asReadOnlyBuffer()

和duplicate一樣,只是不可寫

Compact()

將position和limit之間的字節移到最前面,position=limit-position,這就是這里的壓縮的意思,一般是結束buf操作,將buf寫入輸出流時調用

Position(int)

position=newPosition,如果position<mark,重置mark

Remaining()

返回position和limit之間的字節數

IoBuffer

IoBuffer是MINA內部使用的一個byte buffer,MINA並沒有直接使用NIO 的ByteBuffer。不過IoBuffer 是對 ByteBuffer 的一個封裝。IoBuffer 中的很多方法都是對 ByteBuffer 的直接繼承。只是對 ByteBuffer 添加了一些擴展了更加實用的方法。

基本用法

由於IoBuffer是對Nio的ByteBuffer 的封裝,所以基本概念還是相同的,下面簡單介紹一下:

1、capacity:該屬性描述這個緩沖區最多能緩沖多少個元素,也是Buffer最大存儲元素數,這個值是在創建Buffer的時候指定的,且不能修改。

2、Limit:在從Buffer中向Channel中寫數據時,limit變量指示了還剩多少數據可以讀取,在從Channel中讀取數據到Buffer中時,limit變量指示了還剩多少空間可供存放數據。position正常情況下小於或者等於limit。

3、Position:Buffer實際上也就是個array。當你從Channel中讀數據時,你把從Channel中讀出來的數據放進底層array,position變量用來跟蹤截止目前為止已經寫了多少數據。更精確的講,它指示如果下次寫Buffer時數據應該進入array的哪個位置。因此如果已經從Channel中讀出了3個字節,Buffer的position會被置為3,指向array中第四個位置。

4、Mark:一個可以記憶的Position位置的值,在調用reset()方法時會將緩沖區的Position重置為該索引,並非總是需要定義Mark,但是在定義Mark時,不能將其定義為負數,並且不能讓它大於Position,如果定義了Mark,則在該Position或Limit調整為小於該Mark值時,該Mark將被丟棄。

下面通過一個例子來說明:

i、初始狀態下:

此時position為0,limit和capacity都被設為9;

image

 

ii、從Channel中讀入4個字節數據到Buffer,這時position指向4(第5個):

image

 

iii、在做寫操作之前,我們必須調用一次flip()方法,這個方法做了兩件重要的事情: 
1. 將limit設置到當前的position處。 
2. 設置position為0。

image

 

iiii、執行寫操作后;

image

iv、執行clear后,position設為0,limit設為capition,mark則丟棄;

image

 

 

因為IoBuffer是一個抽象類,不能直接實例化,所有使用的時候需要調用allocate方法來進行內存分配;

allocate有兩種定義:

   1: // Allocates a new buffer with a specific size, defining its type (direct or heap)
   2: public static IoBuffer allocate(int capacity, boolean direct)
   3:  
   4: // Allocates a new buffer with a specific size
   5: public static IoBuffer allocate(int capacity)

這里:

capacity:buffer的大小;

direct:如果為true,則得到direct buffer,如果為false,則得到heap buffer

direct buffer和heap buffer的區別分析:

Direct Buffer不是分配在堆上的,它不被GC直接管理(但Direct Buffer的JAVA對象是歸GC管理的,只要GC回收了它的JAVA對象,操作系統才會釋放Direct Buffer所申請的空間),它似乎給人感覺是“內核緩沖區(buffer in kernel)”。Heap Buffer則是分配在堆上的,或者我們可以簡單理解為Heap Buffer就是byte[]數組的一種封裝形式。當我們把一個Heap Buffer寫入Channel的時候,實際上底層實現會先構建一個臨時的Direct Buffer,然后把Heap Buffer的內容復制到這個臨時的Direct Buffer上,再把這個Direct Buffer寫出去。因此把一個Direct Buffer寫入一個Channel的速度要比把一個Heap Buffer寫入一個Channel的速度要快。但是Direct Buffer創建和銷毀的代價很高,所以要用在盡可能重用的地方。

public static IoBuffer allocate(int capacity)的用法:
   1: // 設置Allocates分配的默認類型,這里設為heap buffer.
   2:  IoBuffer.setUseDirectBuffer(false);
   3:  // 返回一個新的heap buffer.
   4:  IoBuffer buf = IoBuffer.allocate(1024);

 

IoBuffer允許生成一個自動擴展的buffer(這也是沒有選擇使用NIO的ByteBuffer的原因之一);通過設置AutoExpand屬性即可:

   1: IoBuffer buffer = IoBuffer.allocate(8);
   2: buffer.setAutoExpand(true);
   3:  
   4: buffer.putString("12345678", encoder);
   5:        
   6: // Add more to this buffer
   7: buffer.put((byte)10);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM