Java NIO 内置了scatter/gather(分散/聚合)的支持,分散/聚合时通过通道(Channel)读写数据的两个概念。
分散读(Scattering read)是指从通道(Channel)中读取操作时将读取的数据写入多个缓冲区(Buffer)中,也就是 Scatter 代表了数据从通道(Channel)到多个缓冲区(Buffer)的过程。

阅读文章的过程中如果有任何疑问,欢迎添加笔者为好友,拉您进【七日书摘】微信交流群,一起交流技术,一起打造高质量的职场技术交流圈子,抱团取暖,共同进步。
七日书摘官方群.jpg

聚集写(Gathering write)则正好相反,写操作是将多个缓冲区(Buffer)的数据写入同一个通道(Channel)中。

分散/聚合经常用于需要将传输的数据分开处理的场合。举例来说,假设一个消息包含了 header 和 body,我们可能会把 header 和 body 保存在不同独立缓冲区(Buffer) 中,这样就可以分开处理 header 与 body,这样的做法会使开发更简单。

分散读(Scattering Reads)

分散读(Scattering read) 是指把数据从单个通道(Channel) 写入到多个缓冲区(Buffer) 中,下面是示意图:
分散读操作能够读数据从一个通道(Channel)到多个缓冲区(Buffer)。下面是图示例:
scatter.png
Java NIO: Scattering Read

下面展示了 scattering 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 read) 内部必须写满一个 buffer 后才会向后移动到下一个 buffer,因此它不能动态的调整大小,这并不适合消息大小会动态改变的场景,也就是说,如果你有一个header 和 body,并且 header 有一个固定的大小(比如128字节),这种情形下可以正常工作。

聚集写(Gathering Writes)

聚集写(Gathering write) 把多个缓冲区(Buffer)的数据写入到同一个通道(Channel)中,下面是示意图:
gather.png
Java NIO: Gathering Write

下面展示了 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,会按顺序将数组内的内容写进 channel,这里需要注意,写入的时候针对的是 buffer 中 position 到 limit 之间的数据。也就是如果 buffer 的容量是 128 字节,但它只包含了 58 字节数据,那么写入的时候只有 58 字节会真正写入。因此 gathering write 是可以适用于可变大小的 message 的,这和 scattering reads 不同。

英文原文链接:http://tutorials.jenkov.com/java-nio/scatter-gather.html

------完------

推荐阅读:

Java NIO 简明教程 之 Java NIO 概述

Java NIO 简明教程 之 Java NIO Channel

Java NIO 简明教程 之 Java NIO 缓冲(Buffer)

Java基础知识面试题篇(2020年2月最新版)

更技术学习请进入七日书摘官方群: 七日书摘官方群

七日书摘官方群群聊二维码.png

参考资源:
https://blog.csdn.net/u013565163/article/details/83539738
https://blog.csdn.net/Andrew_Yuan/article/details/80215164