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 ...
随机推荐
- NormalMap原理详细解析
NormalMap的实现标志着对渲染流水线的各个环节以及矩阵变化有了正确和深入的认识.这里记录一下学习过程,以及关于NormalMap的诸多细节. 刚开始想要实现NormalMap程序的时候,查阅的是 ...
- 查看linux服务器状态常用命令
最近发现大数据技术的一些部署.高可用.集群等和网站的负载均衡.自动化运维.灾备等其实有很多知识都是重合的,要学好linux运维相关,在大数据的研究上也会有所提高.既然工作需要去系统的去学习linux运 ...
- WCF双工通信笔记
1,Dupex(双工) MEP(消息交换模式),服务端回调(Callback)客户端操作 2,客户端调用服务时,附加上一个回调对象(InstanceContext).服务端处理服务请求时,通过该回调对 ...
- 组队作业_One
Part 1.前言 结对项目作业 结对同学高裕翔的博客 本博文pdf版本 Part 2.PSP表 PSP3.1 Personal Software Process Stages 预估耗时(分钟) 实际 ...
- [转]构建基于WCF Restful Service的服务
本文转自:http://www.cnblogs.com/scy251147/p/3566638.html 前言 传统的Asmx服务,由于遵循SOAP协议,所以返回内容以xml方式组织.并且客户端需要添 ...
- 读<走出软件作坊>有感
1.成功的人都是在不可能完成任务的情况下完成的,成功的人也从来不会抱怨客观条件多么糟糕. 2.公司给你的资源,永远小于你做事需要的资源,这就是现实,就这么多人,就这样的素质,必须在现状中想出做事的办法 ...
- 洛谷P1486 [NOI2004]郁闷的出纳员(splay)
题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...
- plsql导入导出表数据
导出表结构: Tools(工具)-->Export User Objects(导出用户对象) -->选择要导出的表(包括Sequence等)-->.sql文件,导出的都为sql文件 ...
- EBS R12 Vision Profile default value - IRC: Geocode Host
Profile Option Name Site Application Responsibility Server Server Org User IRC: Geocode Host http:// ...
- SOCK开发之---TCP/IP简介
在开发通信程序之前,都要先确定这些程序相互通信所使用的协议(protocol),在深入设计前,我们都需要先从高层次来判断通信由哪个程序发起以及相应在何时产生. 举例来说,一般认为web服务器是一个长时 ...