Java NIO(3)-Scatter/Gather(分散/聚集)
- Java NIO带有内置的分散/聚集支持。分散/聚集概念用于从Channel中写入和从Channel中读取。
- 从Channel中分散读的操作是将数据读取到多个的缓存区(Buffer)中。因此,通道(channel)可以通过scatter将数据分散到多个缓存区buffer中。
- Channel中进行聚集写的操作是将多个缓存区中的数据写入一个单个的通道(channel)中。这样,channel可将数据从多个缓存区聚集到一个通道中。
- Scatter/Gather在你需要处理多部分不同的分离的传输数据时非常实用。例如,如果一条消息包header和body,你可能会把header与body放在不同的分离的缓存区Buffer中。这样做会使得处理header与body变得更加简单。
分散读(Scattering Reads)
- 分散读指将数据从单个通道(channel)读取到多个缓存区(buffer)中。
demo:
ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body = ByteBuffer.allocate(1024);
ByteBuffer[] bufferArray = { header, body };
channel.read(bufferArray);
- 首先注意到先将buffer插入到数组中,然后将数组作为参数传递给channel.read()方法。read方法随后按照各缓存区(buffer)在数组中的顺序写入数据到通道(channel)中。如果缓存区满了,通道会将填充下一个缓存区。
- 事实是,分散读会在移动到下一个缓存区之前填满一个缓存区,这意味着它不适用于动态大小的信息部分。换言之,如果你的消息中有header与body,如果它们的数据包大小都是固定的,分散读才是可行的。
聚集写(Gattering Writes)
- 聚集写是指从多个缓存区(buffer)中写数据到单个通道(channel)中。
demo:
ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body = ByteBuffer.allocate(1024);
//数据写入到缓存区
ByteBuffer[] bufferArray = { header, body };
channel.write(bufferArray);
- header与body的作为write方法的传参,write方法会按照buffer数组在数组中的先后顺序写内容。只有在位点(position)与限度(limit)之间的数据才会被写入。因此,如果一个缓存区有128个字节的容量(capacity),但是只包含了58个字节数据,也就只有这58个字节的数据会被从buffer中写入channel。这样,相对于分散读,聚集写的模式可以很好的支持动态大小的信息数据。