Java NIO学习与记录(三): Scatter&Gather介绍及使用
上一篇知道了
Buffer
的工作机制,以及FileChannel
的简单用法,这一篇介绍下Scatter&Gather
1.Scatter(分散)
用于描述在Channel
中读取的数据分散在不同的Buffer
里。
接着上一篇的例子(rua文件内容为123456789),改造下代码:
1 | readFile = new RandomAccessFile("D:\\rua.txt", "r"); |
上面的代码开了两个Buffer
,然后传给了Channel.read
一个Buffer数组
,运行结果如下:
1 | header里的数据------此时byteRead=4 |
可以看到,文件里的内容被分段加载出来了,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
中去。
来看个例子:
1 | readFile = new RandomAccessFile("D:\\haha.txt", "rw"); |
运行结束后,haha.txt里的内容为:
1 | aabb |
可以看到,最终写入的数据就是按照顺序把两个buffer
里的内容传输进去了。
同样的,还是以网上的协议头数据体的例子说事儿,这个跟Scatter
下的传输方式比较起来就不会那么严格了,看到上面,初始容积为5个字节,但实际写到文件里的每个buffer
仍然是两个字节,因为Gather模式
下,Channel
读取Buffer
数据的时候,只会读取position
到limit
间的数据(可读区域),因此这里不用像多Buffer
读一样要求那么严格,我们可以随意定义header buffer
的长度,只要大于协议头本身长度即可,body buffer
的要求其实是同上,也是大于数据体的长度上限即可。
这就是Scatter
和Gather
的全部内容了~其实简单理解,就是多Buffer
操作,以及对网上那个例子,进行了更详细一点的说明。