Java NIO 笔记03

Java NIO 笔记03,第1张

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文件中相同的内容。
更多内容:我的博客

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4660248.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-06
下一篇 2022-11-06

发表评论

登录后才能评论

评论列表(0条)

保存