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中。下图说明了这个原则。
下面是一个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。如下图描述:
下面的代码是gathering write的一个例子。
ByteBuffer header = ByteBuffer.allocate(128);ByteBuffer body = ByteBuffer.allocate(1024);//write data into buffersByteBuffer[] bufferArray = { header, body };channel.write(bufferArray);复制代码
buffer数组会传递给write方法,它会按照buffer在数组中的顺序依次写入到channel。只有在position和limit之间的数据才会被写入。因此,如果一个buffer的长度为128个字节,但只包含58个字节内容,只有58个字节的内容会被写入到channel。因此,与scattering reads相反,gathering write非常适合动态长度的消息体。