程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java NIO中的通道Channel(二)分散/聚集 Scatter/Gather

Java NIO中的通道Channel(二)分散/聚集 Scatter/Gather

編輯:關於JAVA

Java NIO中的通道Channel(二)分散/聚集 Scatter/Gather。本站提示廣大學習愛好者:(Java NIO中的通道Channel(二)分散/聚集 Scatter/Gather)文章只能為提供參考,不一定能成為您想要的結果。以下是Java NIO中的通道Channel(二)分散/聚集 Scatter/Gather正文


什麼是Scatter/Gather

scatter/gather指的在多個緩沖區上實現一個簡單的I/O操作,比如從通道中讀取數據到多個緩沖區,或從多個緩沖區中寫入數據到通道;

scatter(分散):指的是從通道中讀取數據分散到多個緩沖區Buffer的過程,該過程會將每個緩存區填滿,直至通道中無數據或緩沖區沒有空間;

gather(聚集):指的是將多個緩沖區Buffer聚集起來寫入到通道的過程,該過程類似於將多個緩沖區的內容連接起來寫入通道;

scatter/gather接口

如下是ScatteringByteChannel接口和GatheringByteChannel接口的定義,我們可以發現,接口中定義的方法都傳入了一個Buffer數組;

所謂的scatter/gather操作就是聚集(gather)這個Buffer數組並寫入到一個通道,或讀取通道數據並分散(scatter)到這個Buffer數組中;

public interface ScatteringByteChannel extends ReadableByteChannel
{
    public long read(ByteBuffer[] dsts) throws IOException;

    public long read(ByteBuffer[] dsts, int offset, int length) throws IOException;
}

public interface GatheringByteChannel extends WritableByteChannel
{
    public long write(ByteBuffer[] srcs) throws IOException;

    public long write(ByteBuffer[] srcs, int offset, int length) throws IOException;
}

提醒下,帶offset和length參數的read( ) 和write( )方法可以讓我們只使用緩沖區數組的子集,注意這裡的offset指的是緩沖區數組索引,而不是Buffer數據的索引,length指的是要使用的緩沖區數量;

如下代碼,將會往通道寫入第二個、第三個、第四個緩沖區內容;

int bytesRead = channel.write (fiveBuffers, 1, 3);

注意,無論是scatter還是gather操作,都是按照buffer在數組中的順序來依次讀取或寫入的;

gather寫入

scatter / gather經常用於需要將傳輸的數據分開處理的場合,下面我們看一下一個聚集寫入的示例:


ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body   = ByteBuffer.allocate(1024);

//write data into buffers

ByteBuffer[] bufferArray = { header, body };

channel.write(bufferArray);

以上代碼會將header和body這兩個緩沖區的數據寫入到通道;

這裡要特別注意的並不是所有數據都寫入到通道,寫入的數據要根據position和limit的值來判斷,只有position和limit之間的數據才會被寫入;

舉個例子,假如以上header緩沖區中有128個字節數據,但此時position=0,limit=58;那麼只有下標索引為0-57的數據才會被寫入到通道中;

scatter讀取

如下是一個分散讀取的示例:

ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body   = ByteBuffer.allocate(1024);

ByteBuffer[] bufferArray = { header, body };

channel.read(bufferArray);

以上代碼會將通道中的數據依次寫入到Buffer中,當一個buffer被寫滿後,channel緊接著向另一個buffer中寫;

舉個例子,假如通道中有200個字節數據,那麼header會被寫入128個字節數據,body會被寫入72個字節數據;

好處

更加高效(以下內容摘自《JAVA NIO》);

大多數現代操作系統都支持本地矢量I/O(native vectored I/O)操作。

當您在一個通道上請求一個Scatter/Gather操作時,該請求會被翻譯為適當的本地調用來直接填充或抽取緩沖區,減少或避免了緩沖區拷貝和系統調用;

Scatter/Gather應該使用直接的ByteBuffers以從本地I/O獲取最大性能優勢;

參考資料

《Java NIO》

http://ifeve.com/java-nio-scattergather/

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved