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等的 ...
随机推荐
- Percentage&Last zero&Convert from char to float
Percentage g_rate = wg_header-rate. condense g_rate. SHIFT g_rate RIGHT DELETING TRAILING '0'. REPLA ...
- Django自动获取项目中的全部URL
import re from collections import OrderedDict from django.conf import settings from django.utils.mod ...
- Python开发——函数【基础】
函数的定义 以下规则 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号(). 任何传入参数和自变量必须放在圆括号中间.圆括号之间可以用于定义参数. 函数的第一行语句可以选择性地使用文档字符 ...
- js data日期初始化的5种方法
var objDate=new Date([arguments list]); 参数形式有以下5种: 1)new Date("month dd,yyyy hh:mm:ss"); ...
- Fabric的权限管理:Attribute-Based Access Control
之前稍微了解过Client Identity Chaincode Library,这几天正好开始实际应用. 虽然了解过,还是发现了不少之前理解的不足,也踩了不少坑. 先列出官方介绍: https:// ...
- python之模块的导入
今天在做一个项目的时候卡在模块导入这个点上了.赶紧回头总结一下 一.被导入的文件和工作的脚本在一个目录下 1.导入一个.py文件里的功能或参数(导入模块) 先看一下目录结构: module里有两个功能 ...
- 解决跨域脚本攻击 XSS
配置Content Security Policy 传送门:作者: 阮一峰 http://www.ruanyifeng.com/blog/2016/09/csp.html [前端安全]JavaS ...
- 手动上传图片到nginx下可访问,程序上传后访问图片报403
1. 首先查看文件权限 2. 初步确定是服务器权限问题 2.1 解决方案一:更改文件权限 2.2 解决方案二:修改nginx运行用户 1. 首先查看文件权限 #指令如下 ls -l 2. 初步确定是服 ...
- nigx
1.反向代理 2.负载均衡(weight:设置权重) 3.高可用(场景:当主服务器死掉后 拥有备用服务器承接后续的访问) 安装 Keepalived实现
- Codeforces 1114 简要题解
文章目录 A题 B题 C题 D题 E题 F题 传送门 然而这场div2div2div2没有什么难度比较大的题 A题 传送门 题意简述:三个人分别至少选x,y,zx,y,zx,y,z件物品,有三种物品数 ...