前面的文章分享了Buffer和Channel,以及關於Buffer和Channel的基本操作。這篇文章繼續分享關於Channel的Buffer的操作Scatter和Gather,這篇內容比較簡單。
什麼是Scatter和Gather
Scatter和Gather的字面意思就可以分好的解釋他們各自的用途。其中Scatter的意思是分散,Gather的意思是聚集,我們再來看一下他們是如何分散和聚集的,如下圖所示
當多個Buffer同時向一個Channel中寫資料時,就是聚集也就是Gather。
如何使用
我們用FileChannel來解釋如何使用Scatter和Gather。
Gather
RandomAccessFile randomAccessFile = new RandomAccessFile( "/Users/yangpeng/Documents/360/code/QiwooSample/NIOSample/src/com/nio/sample/file.txt", "rw");
randomAccessFile.seek(0);
FileChannel fileChannel = randomAccessFile.getChannel();
System.out.println("FileChannel position " + fileChannel.position());
ByteBuffer buffer = ByteBuffer.allocate(100);
String str = "hello";
buffer.clear();
buffer.put(str.getBytes());
buffer.flip();
ByteBuffer buffer2 = ByteBuffer.allocate(100);
String str2 = " world";
buffer2.clear();
buffer2.put(str2.getBytes());
buffer2.flip();
ByteBuffer[] bufferArray = {
buffer, buffer2
};
fileChannel.write(bufferArray);
randomAccessFile.close();
fileChannel.close();
複製程式碼
- 通過RandomAccessFile獲得一個FileChannel
- 分別初始化兩個ByteBuffer,裡面分別放入”hello”和”world”兩個字串。
- 初始化一個ByteBuffer陣列,內容為第二步的兩個Buffer
- 把ByteBuffer陣列裡的內容寫入到FileChannel
- 關閉RandomAccessFile和FileChannel
執行完以上幾步之後,我們開啟檔案檢視就是文字里的內容就是”hello world”
注意:寫入的是緩衝區position和limit之間的資料。如果一個緩衝區容量為10位元組,但是僅有5位元組的資料,那麼寫入到通道中的資料就是5個位元組。
Scatter
RandomAccessFile randomAccessFile = new RandomAccessFile( "/Users/yangpeng/Documents/360/code/QiwooSample/NIOSample/src/com/nio/sample/file.txt", "rw");
randomAccessFile.seek(0);
FileChannel fileChannel = randomAccessFile.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(5);
ByteBuffer buffer2 = ByteBuffer.allocate(100);
ByteBuffer[] bufferArray = {buffer, buffer2
};
fileChannel.read(bufferArray);
buffer.flip();
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}System.out.println("");
buffer2.flip();
while (buffer2.hasRemaining()) {
System.out.print((char) buffer2.get());
}randomAccessFile.close();
fileChannel.close();
複製程式碼
- 通過RandomAccessFile獲得一個FileChannel
- 分別初始化兩個ByteBuffer,準備把資料讀到這兩個buffer裡
- 初始化一個ByteBuffer陣列,內容為第二步的兩個Buffer
- 從FileChannel中讀出資料然後寫入到ByteBuffer中
- 關閉RandomAccessFile和FileChannel
執行完以上幾步之後,輸出的內容就是”hello world”
注意:read()方法根據緩衝區陣列中的順序將channel資料寫入。一個緩衝區寫滿後,再往下一個緩衝區寫。
使用場景
適用於寫入或者讀出的資料是固定大小的幾部分。