Java NIO中的通道Channel(二)分散/聚集 Scatter/Gather
什么是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 buffers ByteBuffer[] 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/
Java NIO中的通道Channel(二)分散/聚集 Scatter/Gather的更多相关文章
- 《精通并发与Netty》学习笔记(11 - 详解NIO (二) 分散/聚集 Scatter/Gather、Selector)
一.分散/聚集 Scatter/Gather scatter/gather指的在多个缓冲区上实现一个简单的I/O操作,比如从通道中读取数据到多个缓冲区,或从多个缓冲区中写入数据到通道:scatter( ...
- Java NIO中的通道Channel(一)通道基础
什么是通道Channel 这个说实话挺难定义的,有点抽象,不过我们可以根据它的用途来理解: 通道主要用于传输数据,从缓冲区的一侧传到另一侧的实体(如文件.套接字...),反之亦然: 通道是访问IO服务 ...
- Java NIO学习与记录(三): Scatter&Gather介绍及使用
Scatter&Gather介绍及使用 上一篇知道了Buffer的工作机制,以及FileChannel的简单用法,这一篇介绍下 Scatter&Gather 1.Scatter(分散 ...
- java NIO中的buffer和channel
缓冲区(Buffer):一,在 Java NIO 中负责数据的存取.缓冲区就是数组.用于存储不同数据类型的数据 根据数据类型不同(boolean 除外),提供了相应类型的缓冲区:ByteBufferC ...
- Java NIO中核心组成和IO区别
1.Java NIO核心组件 Java NIO中有很多类和组件,包括Channel,Buffer 和 Selector 构成了核心的API.其它组件如Pipe和FileLock是与三个核心组件共同使用 ...
- Java NIO 三大组件之 Channel
Java NIO 之 Channel 一.什么是Channel Channel用于源节点(例如磁盘)与目的节点的连接,它可以进行读取,写入,映射和读/写文件等操作. 在Java NIO中负责缓冲区中数 ...
- JAVA NIO中的Channels和Buffers
前言 Channels和Buffers是JAVA NIO里面比较重要的两个概念,NIO正是基于Channels和Buffers进行数据操作,且数据总是从Channels读取到Buffers,或者从Bu ...
- Java NIO中的Buffer 详解
Java NIO中的Buffer用于和NIO通道进行交互.如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的.缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO ...
- Java NIO中的缓冲区Buffer(一)缓冲区基础
什么是缓冲区(Buffer) 定义 简单地说就是一块存储区域,哈哈哈,可能太简单了,或者可以换种说法,从代码的角度来讲(可以查看JDK中Buffer.ByteBuffer.DoubleBuffer等的 ...
随机推荐
- Django formset
一 什么是formset Form组件或ModelForm用于做一个表单验证而formset是用于做多个表单的验证组件,用于做批量操作 二 formset的使用方法 1 设置form信息 class ...
- java 遇到的问题
1.list.sort(new Comparator<String>() { @override public int compare(String o1, String o2) { re ...
- Android 获得本地IP地址、外网IP地址、本设备网络状态信息、本地Mac地址
本地内网IP和外网IP的区别: 根据我的经验一台电脑需要两个ip才可以上网,一个是本地的内网ip 一个是外网的ip 本地的ip 一般是192.168.1.2这种样子 只要在不同的路由器上可以重复 外 ...
- tween 缓动动画
在讲tween类之前,不得不提的是贝塞尔曲线了.首先,贝塞尔曲线是指依据四个位置任意的点坐标绘制出的一条光滑曲线.它在作图工具或动画中中运用得比较多,例如PS中的钢笔工具,firework中的画笔等等 ...
- Shell 脚本获取当前目录 和 获得 文件夹名
#!/bin/bash project_path=$(cd ``; pwd) project_name="${project_path##*/}" echo $project_pa ...
- web工程was部署
web.xml调整: 新增如下servlet <servlet> <servlet-name>SimpleFileServlet</servlet-name> &l ...
- Java第四次实验
实验一: Android Stuidio的安装测试: 参考<Java和Android开发学习指南(第二版)(EPUBIT,Java for Android 2nd)>第二十四章: 参考ht ...
- web安全之机器学习入门——1.环境搭建
前置知识 算法和数据的辩证关系:算法和数据是机器学习解决实际问题不可或缺的两大因素.早期机器学习十分依赖特征提取,随着发展,人们发现通过增加训练数据量,让机器从大量基础特征中可以自动关联出潜在关系,自 ...
- Chapter3_操作符_其他操作符
对java中其他操作符及一些注意事项的总结 (1)按位操作符 按位操作符操作基本整数类型中的单个二进制位,有与(&),或(|),非(~).按位操作符还可以和等号(=)联合使用,如~=,& ...
- Linux学习--- C语言关键字、数据类型
关键字: sizeof为关键字,并不是函数. 作用:编译器给我们查看内存空间容量的一个工具. eg:int a: printf("the size is %d\n",sizeof ...