Java NIO 分离器和聚合器,原文地址:http://tutorials.jenkov.com/java-nio/scatter-gather.html
Java NIO 拥有内置的分离器和聚合器。分离器和聚合器是管道进行读写操作时用到的一些东西。
使用分离器可以从一个管道中读取数据写入到多个缓冲区中。因此,管道“分离器”分离了从管道中读出的数据,分别写入到多个缓冲区中。
而使用聚合器可以从多个缓冲区中读出数据写入到一个管道中。因此,管道“聚合器”聚合了多个缓冲区中的数据,然后写入到一个管道中。
当你需要传输多个分离的数据时,分离器和聚合器是非常有用的。例如,一个消息有消息头和消息体组成,你也许会将消息头和消息体放入到不同的缓冲区中以便将消息头和消息体进行分离。
Scattering Reads
读取分离器可以从一个管道中读取数据写入到多个缓冲区。下面的插图展示了这一概念:
下面是使用读取分离器的一个小例子:
从上例可以看到:我们先是将两个字节缓冲区放入到一个数组中,然后把这个数组作为参数传递给 channel.read()
方法。channel.read()
方法会将管道中的数据写入到字节缓冲区数组的元素中,从第一个元素开始,依次写下去。
实际上,读取分离器先向第一个元素中写入数据,然后再转向下一个元素的。所以它不适合有这动态大小的消息。换句话说,如果一个消息有消息头和消息体,并且消息头大小是固定的(例如 128 个字节),那么读取分离器可以如预期运行。
写入聚合器
写入聚合器可以将多个缓冲区的数据写入到同一个管道中。下面的插图展示了这个概念:
下面是使用写入聚合器的一个小例子:
缓冲区数组作为参数传入到 channel.write()
方法中,然后缓冲区数组每个元素中的数据会依次写入到管道中,并且是仅仅写入每个缓冲区 position
和 limit
之间的数据(即尚未读取的数据)。因此,如果一个缓冲区的容量是 128 字节,但是仅仅有 58 字节的数据,那么就只有 58 字节的数据写入到管道中。因此,即使部分消息大小不固定,写入聚合器也可以如预期运行。