Java NIO Buffer 實踐與概念

通過JAVA NIO Buffer 進行讀寫一般需要下面的4步驟:

1、寫入數據到Buffer

2、調用buffer.flip()

3、從Buffer中讀取數據

4、調用buffer.clear()或者buffer.compact()方法

下面我們看一個例子:

public class BuffterClient {
public static void main(String[] args) throws IOException {
RandomAccessFile aFile = new RandomAccessFile("data.txt", "rw");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf); //從Buffer中讀
while (bytesRead != -1) {
buf.flip(); //將寫模式變成讀模式,pos被重置為0
while (buf.hasRemaining()) {
System.out.print((char) buf.get()); //buf.get()讀取數據
}
buf.clear(); //清空Buffer,pos=0,limit=cap
bytesRead = inChannel.read(buf);
}
aFile.close();
}
}

輸出結果:

show me the money1
show me the money2
show me the money3
show me the money4
show me the money5
show me the money6
Process finished with exit code 0

Buffer:

我們可理解成一個內存塊,內存塊需要設置容量,通過Channel開個這個內存塊,內存可以讀寫,順理成章Buffer也支持讀取數據獲取寫入數據到Buffer。

Buffer 三個屬性:

capacity,position,limit ,下面我們看這三個屬性,方便我們理解Buffer的設計思路

Java NIO Buffer 實踐與概念

Capacity:

1、設置內存的容量,可以將capacity bytes,longs 進入Buffer。如果Buffer 滿了,在你寫buffer的時候需要先清空buffer。

Position:

當你寫數據到Buffer的時候,你需要知道position。初始position為0,每次插入數據position會加1

當你從Buffer讀取數據的時候,也需要只是position的位置。flip將寫模式轉換到讀模式,位置被重置為0。

Limit:

限制每次讀取的最大數

Buffer 類型:

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

分配Buffer大小:

ByteBuffer buf = ByteBuffer.allocate(48);

寫入Buffer的兩種方式:

1、通過Channel 寫入數據到Buffer

2、通過Buffer本身的put()方法寫入數據

Flip()方法

將寫模式轉換到讀模式,設置position為0,設置limit=position。

從Buffer中讀取數據的方式:

1、通過Channel讀取數據到Buffer

2、通過Buffer.get()方法

Rewind()方法:

設置position=0,可以進行反覆的讀取Buffer內容

clear()和compact():

buffer.clear()清空緩存,如果緩存有數據則會丟失 ,如果需要未閱讀的數據後面在讀, 可以使用compact()方法代替clear()方法 buffer.compact()方法會將未讀取的數據放到Buffer的頭(使用Unsafe.copyMemory()),最後設置pos為最後未讀元素的最後,不會清空未讀數據

mark()和reset():

通過buffer.mark()方法標記給定的Buffer的位置(pos),後面可以通過buffer.reset()方法將pos回到mark的pos
偽代碼:
buffer.mark()
//call buffer.get()
buffer.reset(); // 設置pos為mark

equals()和compareTo():

equals():
同樣的數據類型(byte,int etc) + 相同數量的字節數 + 所有剩餘的字節數
compareTo():
在兩個buffer進行比較剩餘的元素
所有的元素相等,但是第一個緩存區的元素在第二個緩衝區之前耗盡了數據
與另一個緩衝區中的對應相等的第一個元素小於另一個緩衝區中的元素

代碼地址:https://github.com/yuanzongyu/tutorials/tree/master/core-java-io/src/main/java/xin/clips/nio


分享到:


相關文章: