IoBuffer和ByteBuffer

最近在作通訊和傳輸的項目,大量的使用NIOMina,雖然以前一直對這部分比較關注,可是尚未好好的總結一下這方面的內容。今天想寫點兒NIO裏最基本的一個類ByteBuffer。至於Mina中的IoBuffer,咱們能夠先看Mina API中的描述: java

A byte buffer used by MINA applications. This is a replacement for ByteBuffer. Please refer to ByteBuffer documentation for preliminary usage app

固然,接下去也有寫到:MINA does not use NIO ByteBuffer directly for two reasons,至於這Two Reasons,咱們將在後面的比較中展開。 dom

ByteBuffer繼承了Buffer,對Buffer的理解能夠說是NIO的入門。在Buffer中有4個重要的Attributes ide

Capacity: the capacity is set when the buffer is created and can never be changedspa

Limit: the first element of the buffer that should not be read or written 翻譯

Position: the index of the next element to be read or written code

Mark: a remembered position. Calling mark() set mark=position 繼承

他們的關係以下:0<=mark<=position<=limit<=capacity。 ip


通俗的講: 內存

Capacity:開的內存的大小,一旦設定了,就不能更改了。注意,這裏指的是原生的NIO

Limit:能夠分讀寫來統計。在寫入buffer時,limit表示有多少空間能夠寫入。在從buffer寫出時,limit表示有多少能夠寫出。

Position:下一個要被讀或寫的位置。

Mark:標記位,能夠記住某個position,方便後續操做。

 

對於ByteBuffer有以下經常使用的操做:

flip()::讀寫模式的轉換。

rewind() :將 position 重置爲 0 ,通常用於重複讀。

clear() :清空 buffer ,準備再次被寫入 (position 變成 0 , limit 變成 capacity) 。

compact(): 將未讀取的數據拷貝到 buffer 的頭部位。

mark() 、 reset():mark 能夠標記一個位置, reset 能夠重置到該位置。

get()getShort()等一系列get操做:獲取ByteBuffer中的內容,固然這裏get的內容都是從position開始的,因此要時刻注意position。每次get以後position都會改變。Position的變化是根據你get的類型,若是是short,那就是2byte,若是是int,那就是增長4byte,即32

put()putShort()等一系列put操做:向ByteBuffer添加內容,這裏put的內容都是從position開始的。每次put以後position都會改變。

固然還有allocatehasRemaining等經常使用的方法,不過這些用法通常都不會出錯,使用起來和4attributes也沒有多大相關。特別注意:Buffers are not thread-safe. If you want to access a given buffer concurrently from multiple threads, you will need to do your own synchronization prior to accessing the buffer.至於Buffer或者ByteBuffer有什麼用?那太多了,只要涉及到傳輸、涉及到通訊,均可以用到。固然你也能夠用它最原始的含義,緩衝。

 

好了NIOByteBuffer告一段落,接下來先說IoBuffer中說不用ByteBufferTwo Reasons

It doesn't provide useful getters and putters such as fill, get/putString, and get/putAsciiInt() enough.

It is difficult to write variable-length data due to its fixed capacity

看好了,對於第一點我想也沒什麼,增長了更實用的getString。關鍵是第二點,IoBuffer實現了Auto ExpandAuto Shrink。這就意味了,capacity能夠根據傳輸內容的大小自動變動了。在使用上,咱們能夠這樣寫:

IoBuffer buf = IoBuffer.allocate(1024).setAutoExpand(true);
IoBuffer的源碼中,大部分都使用了原生的 ByteBuffer來實現,這部分採用 allocator來實現。


/** The allocator used to create new buffers */
private static IoBufferAllocator allocator = new SimpleBufferAllocator();
在SimpleBufferAllocator的其中一段allocate:



public ByteBuffer allocateNioBuffer(int capacity, boolean direct) {
        ByteBuffer nioBuffer;
        if (direct) {
            nioBuffer = ByteBuffer.allocateDirect(capacity);
        } else {
            nioBuffer = ByteBuffer.allocate(capacity);
        }
        return nioBuffer;
    }
至於其餘操做,和 ByteBuffer 相似。

貼一段Reilly - Java NIO中的一段代碼做爲結束,後續更多的Mina相關會根據開發進度給出介紹:



import java.nio.CharBuffer;
 
public class BufferFillDrain {
private static int index = 0;
private static String[] strings = { "A random string value",
"The product of an infinite number of monkeys",
"Hey hey we're the Monkees" };
 
private static boolean fillBuffer(CharBuffer buffer) {
 
if (index >= strings.length) {
return false;
}
String string = strings[index++];
 
for (int i = 0; i < string.length(); i++) {
buffer.put(string.charAt(i));
}
return true;
}
 
private static void drainBuffer(CharBuffer buffer){
while(buffer.hasRemaining()){
System.out.println(buffer.get());
}
System.err.println("");
}
 
public static void main(String[] args) {
CharBuffer buffer=CharBuffer.allocate(100);
while(fillBuffer(buffer)){
buffer.flip();
drainBuffer(buffer);
buffer.clear();
}
 
}
}
由於以前作筆記的時候用的都是英文,因此好多都沒有翻譯過來,更好的文檔是官方的文檔,謝謝觀賞。
相關文章
相關標籤/搜索