Java NIO支持scatter/gather。scatter/gather是用于描述读取/写入的概念。 从通道中分散(scattering)读是指一个通道中的数据被读到多个缓冲区。这样,通道中的数据被分散(scatters)到多个缓冲区中了。 往通道中聚合(gathering)写是指写入一个通道中的数据来源于多个缓冲区。这样,多个缓冲区的数据被聚合(gather)到一个通道中了。 scatter/gather 适用于需要将传输的数据分开处理的场合。例如,如果一条信息包含消息头和消息体,可能需要将消息头和消息体分散到不同的缓冲区中,这样方便将消息头和消息体分开处理。
Scattering read是指将一个通路的数据读到多个buffer中。如下图:
Scattering Reads
代码示例如下:
ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body = ByteBuffer.allocate(1024);
ByteBuffer[] bufferArray = {header, body};
channel.read(bufferArray);
注意,缓冲区先被插入到数组,然后将数据作为channel.read()方法的参数。read()方法按照缓冲区在数组中的顺序将通路中的数据写入。一个缓冲区写满后,通路接着往下一个缓冲区写。 事实上Scattering read移动到下一个缓冲区之前,必须写满当前的缓冲区,这意味着它不适于大小动态变化的消息。换句话说,如果存在消息头和消息体,消息头的大小固定(例如128字节),这个方法才能正常工作
gathering write是指把多个缓冲区中的数据写入一个通路。如下图所示:
Gathering Write
代码示例如下:
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字节。因此和Scattering reads相反,gathering write处理大小动态变化的消息是正常的。