Java NIO Scatter 和 Gather

Java NIO带有内置的scatter和gather支持。scatter和gather是在读取和写入Channel中使用的概念。

从Channel的scatter read是将数据读取到多个缓冲区。因此,将数据从通道“分散”到多个缓冲区中。

gather write到Channel是一种写操作,它将来自多个缓冲区的数据写到单个Channel中。因此,将来自多个缓冲区的数据“收集”到一个通道中。

在需要分别处理传输数据的各个部分的情况下,scatter和gather可能非常有用。例如,如果消息由标题和正文组成,则可以将标题和正文保留在单独的缓冲区中。这样做可以更轻松地分别使用标题和正文。


1.Scattering Reads

“分散读取”将数据从单个通道读取到多个缓冲区中。这是该原理的说明:

scatter.png


这是一个代码示例,显示了如何执行分散读取:

ByteBuffer header = ByteBuffer.allocate(128);

ByteBuffer body   = ByteBuffer.allocate(1024);



ByteBuffer[] bufferArray = { header, body };



channel.read(bufferArray);


注意如何将缓冲区首先插入到数组中,然后将数组作为参数传递给channel.read()方法。然后,read()方法按照缓冲区在数组中出现的顺序从通道写入数据。一旦缓冲区已满,通道将继续填充下一个缓冲区。

分散读取会在进入下一个缓冲区之前填满一个缓冲区,这一事实意味着它不适合动态调整大小。换句话说,如果有标头和正文,并且标头是固定大小(例如128字节),则分散读取适用。


2.Gathering Writes

“聚集写入”将来自多个缓冲区的数据写入单个通道。这是该原理的说明:

gather.png


这是一个代码示例,显示了如何执行聚集写入:

ByteBuffer header = ByteBuffer.allocate(128);

ByteBuffer body   = ByteBuffer.allocate(1024);



//write data into buffers



ByteBuffer[] bufferArray = { header, body };



channel.write(bufferArray);


缓冲区数组被传递到write()方法,该方法按照缓冲区在数组中的顺序写入缓冲区的内容。仅写入缓冲区的position和limit之间的数据。因此,如果缓冲区的容量为128个字节,但仅包含58个字节,则只有58个字节从该缓冲区写入通道。因此,与分散读取相比,聚集写入对于动态大小的部分也可以很好地工作。


 

展开阅读全文