栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java NIO 笔记03

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java NIO 笔记03

Java NIO 的分散(scatter)/聚集(gather)

更多内容:我的博客
分散(scatter)和聚集(gather)是用于从通道读取和写入的概念。从通道分散读取是一种将数据读入多个缓冲区(Buffer)的读取操作,也就是将来自通道的数据分散到多个缓冲区中。

对通道的聚集写入是一种将数据从多个缓冲区写入单个通道的写入操作。因此,通道将来自多个缓冲区的数据“聚集”到一个通道中。在需要分别处理传输数据的各个部分的情况下,分散/聚集是非常有用的。例如,如果消息是由标题和正文组成的,我们可以将标题和正文保存在单独的缓冲区。这样可以轻松的分别处理标题和正文。

分散读取(scatter reads)

将数据从单个通道(channel)读取到多个缓冲区(Buffer)。如下图:

代码:

ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body = ByteBuffer.allocate(1024);

ByteBuffer[]bufferArray = {header, body};
channel.read(bufferArray);

上面我们首先分配了俩个缓冲区,然后把它们插入到一个bufferArray的数组中,因为channel的read方法除了可以接受ByteBuffer还可以接受ByteBuffer数组,然后read方法会按照缓冲区(buffer)在数组中出现的顺序从channel中写入数据,一旦缓冲区满了以后,通道就会继续填充下一个缓冲区。由于分散读取在进入下一个缓冲区时上一个缓冲区已经被填满,所以它不适合动态大小的消息部分。也就是说如果消息中的header部分的大小是固定的,例如上面代码中的128字节,那么分散读取是适用的。

聚集写入(gather writers)

聚集写入就是从多个缓冲区写入到单个通道中,如图:

代码:

ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body = ByteBuffer.allocate(1024);

//写入数据到channel中
ByteBuffer[]bufferArray = {header, body};
channel.write(bufferArray);

ByteBuffer数组传入write方法后,该方法将缓冲区中的数据按照它们在数组中的顺序写入到channel中。写入时仅写入position到limit的数据,例如我们header定义了128字节,但是实际只有58字节,那么写入时只会写入58字节。因此,与分散读取相比,聚集写入对动态大小的消息部分正常工作。

个人完整实例

该实例展示了分散读取和聚集写入,控制台打印了俩部分内容,并且使用聚集写入将内容复制到另外一个文件内

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class ScatterAndGather {
	private final static String readFilePath = "C:\temp\test1.txt";
	private final static String writeFilePath = "C:\temp\test2.txt";
	
	public static void main(String[] args) {
		scatterReadsAndGatherWrite(readFilePath, writeFilePath);
	}
	
	
	public static void scatterReadsAndGatherWrite(String readFilePath, String writeFilePath) {
		try(
			RandomAccessFile readFile = new RandomAccessFile(readFilePath, "rw");
			RandomAccessFile writeFile = new RandomAccessFile(writeFilePath,"rw"); 
			FileChannel readChannel = readFile.getChannel();	//获取channel
			FileChannel wirteChannel = writeFile.getChannel();
		){
			ByteBuffer header = ByteBuffer.allocate(48);	//header缓冲区
			ByteBuffer content = ByteBuffer.allocate(1024);	//content缓冲区
			ByteBuffer[]bufferArray = {header, content};	//组成数组,先读取header,header缓冲区满了以后再读取到content缓冲区
			while(readChannel.read(bufferArray) != -1) {
				for(int i=0; i");
					}
					if(i==1) {
						System.out.println();
						System.out.print("content=>");
					}
					while(bufferArray[i].hasRemaining()) {
						System.out.print((char)bufferArray[i].get());
					}
					bufferArray[i].rewind();	//将position重置为0,为了下面的聚集读取,具体rewind()方法介绍可参考Java NIO 笔记02中的介绍
				}
				//test1.txt中的内容写入到test2.txt中
				wirteChannel.write(bufferArray);
				for(int i=0; i 

test1.txt中内容如下:

[-------------this is header parts-------------][----------this is content paras,welcome from www.huhailong.vip---------]

控制台运行结果如下:

并且test2.txt中已经存在于test1.txt文件中相同的内容。
更多内容:我的博客

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/332855.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号