Java NIO学习与记录(三): Scatter&Gather介绍及使用
上一篇知道了Buffer的工作机制,以及FileChannel的简单用法,这一篇介绍下 Scatter&Gather
1.Scatter(分散)
用于描述在Channel中读取的数据分散在不同的Buffer里。
接着上一篇的例子(rua文件内容为123456789),改造下代码:
readFile = new RandomAccessFile("D:\\rua.txt", "r");
FileChannel readChannel = readFile.getChannel();
ByteBuffer first = ByteBuffer.allocate(2); //第一块buffer
ByteBuffer second = ByteBuffer.allocate(2); //第二块buffer
ByteBuffer[] byteBuffers = {first, second};
long bytesRead = readChannel.read(byteBuffers); //从通道里读取数据到Buffer内(最大不超过Buffer容积)
while (bytesRead != -1) { //当读不到任何东西时返回-1
System.out.println("\nheader里的数据------此时byteRead=" + bytesRead);
first.flip(); //切换到Buffer读模式,读模式下可以读取到之前写入Buffer的数据
while (first.hasRemaining()) {
System.out.print("-" + (char) first.get()); //第一块Buffer读出的数据用减号分割,用于跟第二块区分
}
first.clear();
System.out.println("\nbody里的数据------此时byteRead=" + bytesRead);
second.flip();
while (second.hasRemaining()) {
System.out.print("+" + (char) second.get()); //第二块Buffer读出的数据用加号分割,用于跟第一块区分
}
second.clear(); // 切换回Buffer的写模式
System.out.println("\n----------------------------------------------");
bytesRead = readChannel.read(byteBuffers); //跟上面一样,再次从通道读取数据到Buffer中
}
System.out.print("\n-----------程序结束");
上面的代码开了两个Buffer,然后传给了Channel.read一个Buffer数组,运行结果如下:
header里的数据------此时byteRead=4
-1-2
body里的数据------此时byteRead=4
+3+4
----------------------------------------------
header里的数据------此时byteRead=4
-5-6
body里的数据------此时byteRead=4
+7+8
----------------------------------------------
header里的数据------此时byteRead=1
-9
body里的数据------此时byteRead=1
----------------------------------------------
-----------程序结束
可以看到,文件里的内容被分段加载出来了,first buffer里首选读取一段,然后接着second buffer再接着读取接下来的一段。上面例子符合Scatter的描述。
看过网上一些文章,说的最多的例子就是协议头数据体分开处理的例子:
假设通过Channel获取到的数据存在固定长度的协议头,以及已知最大长度限制的数据体,就可以通过两个Buffer来接收,一个是header buffer,一个是body buffer,
但这个对数据要求很严苛,结合上面的例子,不难发现,想要做到准确无误的处理这个例子,就得要求事先必须知道header的长度,以及数据体的最大长度上限,为什么要这样呢?因为如果不知道header的长度,那么header buffer就可能会读到body buffer里的东西或者body buffer里读到header buffer里的东西,如果不知道body的上限长度,那么如果body数据长度超过了body buffer的长度,body里的数据就会再次读到header buffer中去(这个可以结合上面的例子理解)。
2.Gather(聚集)
用于描述在将不同Buffer里的数据写到同一个Channel中去。
来看个例子:
readFile = new RandomAccessFile("D:\\haha.txt", "rw");
FileChannel channel = readFile.getChannel();
ByteBuffer first = ByteBuffer.allocate(5); //第一块buffer
ByteBuffer second = ByteBuffer.allocate(5); //第二块buffer
first.put("aa".getBytes());
second.put("bb".getBytes());
first.flip();
second.flip();
ByteBuffer[] byteBuffers = {first, second};
channel.write(byteBuffers);
System.out.print("\n-----------程序结束");
运行结束后,haha.txt里的内容为:
aabb
可以看到,最终写入的数据就是按照顺序把两个buffer里的内容传输进去了。
同样的,还是以网上的协议头数据体的例子说事儿,这个跟Scatter下的传输方式比较起来就不会那么严格了,看到上面,初始容积为5个字节,但实际写到文件里的每个buffer仍然是两个字节,因为Gather模式下,Channel读取Buffer数据的时候,只会读取position到limit间的数据(可读区域),因此这里不用像多Buffer读一样要求那么严格,我们可以随意定义header buffer的长度,只要大于协议头本身长度即可,body buffer的要求其实是同上,也是大于数据体的长度上限即可。
这就是Scatter和Gather的全部内容了~其实简单理解,就是多Buffer操作,以及对网上那个例子,进行了更详细一点的说明。
Java NIO学习与记录(三): Scatter&Gather介绍及使用的更多相关文章
- Java NIO学习与记录(八): Reactor两种多线程模型的实现
Reactor两种多线程模型的实现 注:本篇文章例子基于上一篇进行:Java NIO学习与记录(七): Reactor单线程模型的实现 紧接着上篇Reactor单线程模型的例子来,假设Handler的 ...
- Java NIO 学习笔记(三)----Selector
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
- Java NIO学习与记录(五): 操作系统的I/O模型
操作系统的I/O模型 在开始介绍NIO Reactor模式之前,先来介绍下操作系统的五种I/O模型,了解了这些模型,对理解java nio会有不小的帮助. 先来看下一个服务端处理一次网络请求的流程图: ...
- Java NIO学习与记录(二):FileChannel与Buffer用法与说明
FileChannel与Buffer用法与说明 上一篇简单介绍了NIO,这一篇将介绍FileChannel结合Buffer的用法,主要介绍Buffer FileChannel的简单使用&Buf ...
- Java NIO学习与记录(七): Reactor单线程模型的实现
Reactor单线程模型的实现 一.Selector&Channel 写这个模型需要提前了解Selector以及Channel,之前记录过FileChannel,除此之外还有以下几种Chann ...
- Java NIO学习与记录(六): NIO线程模型
NIO线程模型 上一篇说的是基于操作系统的IO处理模型,那么这一篇来介绍下服务器端基于IO模型和自身线程的处理方式. 一.传统阻塞IO模型下的线程处理模式 这种处理模型是基于阻塞IO进行的,上一篇讲过 ...
- Java NIO学习与记录(一):初识NIO
初识 工作中有些地方用到了netty,netty是一个NIO框架,对于NIO却不是那么熟悉,这个系列的文章是我在学习NIO时的一个记录,也期待自己可以更好的掌握NIO. 一.NIO是什么? 非阻塞式I ...
- Java NIO学习与记录(四): SocketChannel与BIO服务器
SocketChannel与BIO服务器 SocketChannel可以创建连接TCP服务的客户端,用于为服务发送数据,SocketChannel的写操作和连接操作在非阻塞模式下不会发生阻塞,这篇文章 ...
- Java NIO 学习笔记(二)----聚集和分散,通道到通道
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
随机推荐
- 利率计算--web版--软件工程
1.客户说:帮我开发一个复利计算软件. 完成复利公式计算程序,并成功PUSH到github上. 截止时间:3.10晚12点之前. 按照这个要求完成了. 演示. 计算:本金为100万,利率或者投资回报率 ...
- [mongoDB] mongoDb
mongodb memcached redis kv数据库(key/value) mongodb 文档数据库,存储的是文档(Bson->json的二进制化). 特点:内部执行引擎为 ...
- Spring源码解析 - BeanFactory
BeanFactory是Spring实现依赖注入的核心接口.提供应用的统一配置注册功能,实现业务开发解偶.使用getBean可以代替单例,原型设计模式. 顶重要的BeanFactory里注释写得太好了 ...
- C# WebApi 过滤器的使用开发接口必备利器
在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理.引入了这一机制可以更好地践行DRY(Don’t Repeat Yourself)思想 ...
- mysql - json串新增字段
1.建表 -- 建表 drop table if exists ta_product2; CREATE TABLE ta_product2( id int primary key auto_incre ...
- 企业搜索引擎开发之连接器connector(十八)
创建并启动连接器实例之后,连接器就会基于Http协议向指定的数据接收服务器发送xmlfeed格式数据,我们可以通过配置http代理服务器抓取当前基于http协议格式的数据(或者也可以通过其他网络抓包工 ...
- prog1,2,3
1.第一版本程序Prog1:+ 给定一个数组,实现数组元素求和:具体要求:实现对一维数组(a[100])的所有元素相加运算.+ 数据准备:a)数组长度:100:b)数组数据来源:实验数据A列:1~10 ...
- C#学习(1):类型约束
where T : class泛型类型约束 类型参数约束,.NET支持的类型参数约束有以下五种: where T : struct | T必须是一个结构类型 where T : class T必须是一 ...
- [Oracle]Oracle数据库CPU利用率很高解决方案
Oracle数据库经常会遇到CPU利用率很高的情况,这种时候大都是数据库中存在着严重性能低下的SQL语句,这种SQL语句大大的消耗了CPU资源,导致整个系统性能低下.当然,引起严重性能低下的SQL语句 ...
- 开源日志收集Exceptionless简单使用
这两天在研究一个开源的日志收集工具Exceptionless 官网地址:https://exceptionless.com/GitHub地址:https://github.com/exceptionl ...