Java NIO内置了对scatter / gather(分散/聚集)的支持。分散/聚集是在用在从Channel
读取数据或往Channel
写入数据时的概念。
分散读指的是从一个Channel
将数据读入多个Buffer
。因此,Channel
将数据分散到了多个Buffer
。
聚集写指的是将多个Buffer
的数据写入单个Channel
。因此Channel
将多个Buffer
的数据聚集了起来。
在需要分别处理数据各个部分的时候,分散/聚集非常有用。比如,一条消息包含header和body两部分,你可以将他们放到不同的Buffer
里。这样你就可以分开处理header和body了。
Scattering Reads
分散读指的是从一个Channel
将数据读入多个Buffer
。如下图所示:
以下是如何进行分散读的示例代码:
ByteBuffer header = ByteBuffer.allocate(48);
ByteBuffer body = ByteBuffer.allocate(1024);
ByteBuffer[] bufferArray = new ByteBuffer[] { header, body };
channel.read(bufferArray);
注意这些Buffer
是怎么首先插入数组,然后作为参数传递给channel.read()
方法的。read()
方法会按照他们在数组中的顺序将数据读入其中。当一个Buffer
被写满后,Channel
将继续往下一个Buffer
填充数据。
分散读在读满一个Buffer
之前不会往下一个Buffer
读入数据,意味着对于各个部分大小不固定的消息,它并不适用。换句话说,如果你的消息体有header和body两部分,且header大小固定(比如128字节),那么分散读就很好用。
Gathering Writes
聚集写指的是将多个Buffer
的数据写入单个Channel
。如下图所示:
以下是如何进行聚集写的示例代码:
ByteBuffer header = ByteBuffer.allocate(48);
ByteBuffer body = ByteBuffer.allocate(1024);
// 往header和body里写数据
ByteBuffer[] bufferArray = new ByteBuffer[] { header, body };
channel.write(bufferArray);
同样,write
方法会按照Buffer
在数组中的顺序将数据写入Channel
。并且只写Buffer
中在position
和limit
之间的数据。因此,如果个一个Buffer
有128字节的capacity
,但只有58字节的数据,那么只有这58字节会被写入Channel
。所以,与分散读相比,聚集写能很好的处理动态大小的消息各个部分。
说明
发现貌似有人在看这个系列文章了,有必要说明下,这个Java NIO系列来源于jenkov.com,本文只是翻译,希望大家千万不要误会,本文不是原创。原文地址:Java NIO。
网友评论