1. 程式人生 > 實用技巧 >Java NIO之Buffer(緩衝區)

Java NIO之Buffer(緩衝區)

​ Java NIO中的快取區(Buffer)用於和通道(Channel)進行互動。資料是從通道讀入緩衝區,從緩衝區寫入到通道中的。

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

Buffer底層使用陣列實現。


1、NIO 資料讀取基本操作示意

2、Java NIO中Buffer型別

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

  • ByteBuffer
  • MappedByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer


3、Buffer的基本用法

​ 使用Buffer讀寫資料一般遵循以下四個步驟:

​ 寫入資料到Buffer;

​ 呼叫flip()方法;

​ 從Buffer中讀取資料;

​ 呼叫clear()方法或者compact()方法;

​ 當向buffer寫入資料時,buffer會記錄下寫了多少資料。一旦要讀取資料,需要通過flip()方法將Buffer從寫模式切換到讀模式。在讀模式下,可以讀取之前寫入到buffer的所有資料。

​ 一旦讀完了所有的資料,就需要清空緩衝區,讓它可以再次被寫入。有兩種方式能清空緩衝區:呼叫clear()或compact()方法。clear()方法會清空整個緩衝區。compact()方法只會清除已經讀過的資料。任何未讀的資料都被移到緩衝區的起始處,新寫入的資料將放到緩衝區未讀資料的後面。

String str = "charBuffer";
CharBuffer charBuffer = CharBuffer.allocate(1024);
charBuffer.put(str);
charBuffer.append("--");
charBuffer.append("hello world");

charBuffer.flip();

//單個讀取buffer中的內容
/*while (charBuffer.hasRemaining()) {
    System.out.println(charBuffer.get());
}*/

//一次性讀取buffer中的內容
char[] dst = new char[charBuffer.limit()];
charBuffer.get(dst);
System.out.println(new String(dst));

4、Buffer屬性與方法詳解

4.1、基本屬性
public abstract class Buffer {
    // Invariants: mark <= position <= limit <= capacity
    private int mark = -1;//標記位置 
    private int position = 0;//當前遊標位置
    private int limit;//可讀取資料大小
    private int capacity;//buffer容量大小   
    ...  
}        

4.2、常用方法
4.2.1、mark()

標記當前位置,配合reset使用。

public final Buffer mark() {
    mark = position;
    return this;
}
4.2.2、reset()

重置遊標為標記位。

public final Buffer reset() {
    int m = mark;
    if (m < 0)
        throw new InvalidMarkException();
    position = m;
    return this;
}
4.2.3、clear()

清除緩衝區,等待寫入。

public final Buffer clear() {
    position = 0;
    limit = capacity;
    mark = -1;
    return this;
}
4.2.4、flip()

將緩衝區由寫模式切換為讀模式。

public final Buffer flip() {
    limit = position;
    position = 0;
    mark = -1;
    return this;
}
4.2.5、rewind()

重置buffer,等待寫入。

public final Buffer rewind() {
    position = 0;
    mark = -1;
    return this;
}
4.2.6、remaining()

獲取剩餘可讀元素個數。

public final int remaining() {
    return limit - position;
}
4.2.7、hasRemaining()

判斷是否還有可讀元素。

public final boolean hasRemaining() {
    return position < limit;
}