NIO支持scatter/gather。Scatter/Gather概念适用于从Channel读写数据的场景。
- 分散读(Scattering Read)是指将channel的数据读出写入多个Buffer中的操作。正如字面所表达的,将Channel的数据 读出,并“分散”(Scattering)到多个Buffer中
- 聚集写(Gathering Write)是指将多个Buffer的数据写到同一个channel中的操作。因此channel“聚集”(Gathering)了多个Buffer的数据
Scatter/Gathering适用于需要将传输的数据分开处理的场景。比如说,传输一个由header和body组成的消息,你可能需要把两个部分保存在不同的buffer里,以方便分开处理。
Scattering Read(分散读)
“Scattering Read”将一个Channel中的数据读入不同的Buffer中。下图是一个Scattering Read示例:
下面是Scattering Read的代码说明:
ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body = ByteBuffer.allocate(1024);
ByteBuffer[] bufferArray = { header, body };
channel.read(bufferArray);
注意:这段代码先将buffer对象插入数组,然后整个数组作为Channel.read()的入参。read()方法会按照ByteBuffer数组中元素的位置将数据从Channel读出 向 buffer写入。一旦这个Buffer满了,就会立即填充下个Buffer。
Scattering Read只在写满一个Buffer后才填充下个的特性其实说明了Scattering Read不适用于大小不固定的动态消息。也就是说,如果一个消息有Header和body,而且header大小固定, 那么Scattering Read才适用。
Gathering Write
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);
write()方法接收Buffer数组作为传参,会按照数组中Buffer元素顺序依次将Buffer中内容写入到Channel中。一个buffer的position和limit之间的内容才会被写入。因此,如果一个BUffer有128字节的容量,但实际只有58个字节的数据,那只有这58个字节会被写入到Channel中。因此,Gathering Write适用于大小不定的消息,这点倒是和Scattering Read不同。