五、Java NIO Scatter / Gather

所有文章

https://www.cnblogs.com/lay2017/p/12901123.html

 

正文

在前面的文章中,我们默认了一个规则。就是默认了一个Channel对应了一个Buffer,它们之间的读写发生在一对一关系里。事实上,Channel是可以对应多个Buffer的,也就是一对多关系。

当一个Channel向多个Buffer写入数据的时候,称作分散(Scatter)

当一个Channel从多个Buffer读取数据的数据,称作聚集(Gather)

分散读取(Scattering Read)

分散读取意味着从一个Channel中读取数据到多个Buffer里面。如图:

 

 

 以下是示例代码

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

ByteBuffer[] bufferArray = { header, body };

channel.read(bufferArray);

注意,示例中首先创建了两个Buffer:header、body,分别具备固定大小。header、body再放到一个array当中。Channel向Buffer读数据的时候入参是array。

我们关注一个read方法的逻辑,read方法传入了两个Buffer。当第一个Buffer满了以后,才会开始往第二个Buffer填充数据。也就是说其内部是遍历Buffer来填充数据的,当前一个Buffer没有满的情况下是不会移动到下一个Buffer的。这意味着,分散读取到多个Buffer并不适用于大小是动态的。换句话说,如果header的大小不是固定的,那么使用过程中可能就会出现body的数据在header的Buffer中,这就造成了一些问题。所以分散读取到多个Buffer,需要Buffer大小相对固定。

聚集写入(gathering write)

聚集写入,是将多个Buffer的数据写入到一个Channel当中,如图

 

 以下是示例代码

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

//write data into buffers

ByteBuffer[] bufferArray = { header, body };

channel.write(bufferArray);

类似地,传入了多个Buffer。当write方法执行地时候,会按照顺序从Buffer中读入数据,并写入到Channel当中。不过和分散读不同地是,聚集写不需要Buffer固定大小。一个Buffer只要读完数据就会换下一个Buffer。

 

posted @ 2020-05-17 17:18  __lay  阅读(241)  评论(0编辑  收藏  举报