5 Java NIO Scatter 与Gather-翻译

238 阅读2分钟

Java NIO开始支持scatter与gatter。scatter与gatter用于实现从Channel读数据和向通道写数据。

scatter从一个通道读取数据并写入到多个Buffer中。因此,scatter实现将通道中的数据写入到多个Buffer中去。

gatter负责将多个buffer中的数据写入到一个channel。因此,gatter实现将多个buffer中的数据聚集到一个channel中去。

scatter和gatter经常用于将需要传输的数据分开处理的场合,例如,如果一条消息由消息头跟消息体组成,你经常需要将消息头与消息体放在不同的buffer中,这样你可以更加方便地处理消息头跟消息体。

Scattering Reads

"scattering read"是将一个Channel的数据读入到多个Buffer中。下图说明了这个原则。

image
下面是一个scatter read的一个例子。

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

ByteBuffer[] bufferArray = { header, body };

channel.read(bufferArray);

注意到buffer首先被插入到数组,然后将数组作为参数传递给channel.read()方法。read方法按照buffer在数组中的顺序依次读取。当一个buffer满了以后,就往下一个buffer中写数据。

scattering reads在移动到下一个buffer之前会先写满当前buffer。这意味着它不适合动态消息体的情况。换句话说,如果你有一个消息头和消息体,并且消息头的长度是固定的,那么scattering read将会非常适合。

Gathering Writes

"gathering write"是从多个buffer中写入数据到单个channel。如下图描述:

image

下面的代码是gathering write的一个例子。

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。只有在position和limit之间的数据才会被写入。因此,如果一个buffer的长度为128个字节,但只包含58个字节内容,只有58个字节的内容会被写入到channel。因此,与scattering reads相反,gathering write非常适合动态长度的消息体。