IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java NIO 笔记03 -> 正文阅读

[Java知识库]Java NIO 笔记03

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

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

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

分散读取(scatter reads)

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

scatter reads

代码:

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)

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

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);
	}
	
	/**
	 * 该实例将展示读取文件中的内容,控制台分别打印header部分和content部分,并且将文件中的内容通过聚集写入的方式写入到test2.txt文件中
	 * @param path 文件路径
	 */
	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<bufferArray.length; i++) {
					bufferArray[i].flip();
					if(i==0) {
						System.out.print("header=>");
					}
					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<bufferArray.length; i++) {
					bufferArray[i].clear();
				}
			}
			
		}catch(IOException e) {
			e.printStackTrace();
		}
	}

}

test1.txt中内容如下:

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

控制台运行结果如下:

在这里插入图片描述

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

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-18 17:15:46  更:2021-10-18 17:18:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:13:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码