博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java NIO中的通道Channel(二)分散/聚集 Scatter/Gather
阅读量:5924 次
发布时间:2019-06-19

本文共 2126 字,大约阅读时间需要 7 分钟。

什么是Scatter/Gather

scatter/gather指的在多个缓冲区上实现一个简单的I/O操作,比如从通道中读取数据到多个缓冲区,或从多个缓冲区中写入数据到通道;

scatter(分散):指的是从通道中读取数据分散到多个缓冲区Buffer的过程,该过程会将每个缓存区填满,直至通道中无数据或缓冲区没有空间;

gather(聚集):指的是将多个缓冲区Buffer聚集起来写入到通道的过程,该过程类似于将多个缓冲区的内容连接起来写入通道;

scatter/gather接口

如下是ScatteringByteChannel接口和GatheringByteChannel接口的定义,我们可以发现,接口中定义的方法都传入了一个Buffer数组;

所谓的scatter/gather操作就是聚集(gather)这个Buffer数组并写入到一个通道,或读取通道数据并分散(scatter)到这个Buffer数组中;

public interface ScatteringByteChannel extends ReadableByteChannel{    public long read(ByteBuffer[] dsts) throws IOException;    public long read(ByteBuffer[] dsts, int offset, int length) throws IOException;}public interface GatheringByteChannel extends WritableByteChannel{    public long write(ByteBuffer[] srcs) throws IOException;    public long write(ByteBuffer[] srcs, int offset, int length) throws IOException;}

提醒下,带offset和length参数的read( ) 和write( )方法可以让我们只使用缓冲区数组的子集,注意这里的offset指的是缓冲区数组索引,而不是Buffer数据的索引,length指的是要使用的缓冲区数量;

如下代码,将会往通道写入第二个、第三个、第四个缓冲区内容;

int bytesRead = channel.write (fiveBuffers, 1, 3);

注意,无论是scatter还是gather操作,都是按照buffer在数组中的顺序来依次读取或写入的;

gather写入

scatter / gather经常用于需要将传输的数据分开处理的场合,下面我们看一下一个聚集写入的示例:

 
ByteBuffer header = ByteBuffer.allocate(128);ByteBuffer body   = ByteBuffer.allocate(1024);//write data into buffersByteBuffer[] bufferArray = { header, body };channel.write(bufferArray);

以上代码会将header和body这两个缓冲区的数据写入到通道;

这里要特别注意的并不是所有数据都写入到通道,写入的数据要根据position和limit的值来判断,只有position和limit之间的数据才会被写入;

举个例子,假如以上header缓冲区中有128个字节数据,但此时position=0,limit=58;那么只有下标索引为0-57的数据才会被写入到通道中;

scatter读取

如下是一个分散读取的示例:

ByteBuffer header = ByteBuffer.allocate(128);ByteBuffer body   = ByteBuffer.allocate(1024);ByteBuffer[] bufferArray = { header, body };channel.read(bufferArray);

以上代码会将通道中的数据依次写入到Buffer中,当一个buffer被写满后,channel紧接着向另一个buffer中写;

举个例子,假如通道中有200个字节数据,那么header会被写入128个字节数据,body会被写入72个字节数据;

好处

更加高效(以下内容摘自《JAVA NIO》);

大多数现代操作系统都支持本地矢量I/O(native vectored I/O)操作。

当您在一个通道上请求一个Scatter/Gather操作时,该请求会被翻译为适当的本地调用来直接填充或抽取缓冲区,减少或避免了缓冲区拷贝和系统调用;

Scatter/Gather应该使用直接的ByteBuffers以从本地I/O获取最大性能优势;

参考资料

《Java NIO》

http://ifeve.com/java-nio-scattergather/

转载于:https://www.cnblogs.com/chenpi/p/6483431.html

你可能感兴趣的文章
怎样将语音转换成文字
查看>>
为什么学习C语言这么久,看的懂代码,做不出题没项目
查看>>
RIP基本概念
查看>>
老板让你抗住千万级流量,如何做架构设计?
查看>>
程序员面试,为什么不跟我谈高并发?
查看>>
解决Windows Server 2008 R2无法保存网络发现状态更改问题
查看>>
SQL SELECT INTO 语句
查看>>
我的友情链接
查看>>
Tomcat 系统架构与设计模式
查看>>
JAVA类的生命周期
查看>>
Linux服务器部署系列之七—OpenLDAP篇
查看>>
Python 在Ubuntu下的开发环境搭建
查看>>
沃通WoSign:关于微信公告“iOS11不再信赖WoSign证书”的说明
查看>>
CENTOS客户端加载ISCSI配置方法。
查看>>
11月全球操作系统版本份额混战:XP仅为13.57%
查看>>
10月8日“.我爱你”域名总量:耐思尼克升至十一名
查看>>
12月第3周网络安全报告:发现放马站点域名131个
查看>>
k8s集群之kubernetes-dashboard和kube-dns组件部署安装
查看>>
sed命令使用
查看>>
LAMP架构(Apache访问日志不记录静态文件、访问日志切割、静态元素过期时间)...
查看>>