NIO - Scatter/Gather

分散/聚集 I/O(scatter-gather I/O) 概述 分散/聚集 I/O是一种可以在单次系统调用中对多个缓冲区输入输出的方法,可以把多个缓冲区的数据写到单个数据流,也可以把单个数据流读到多个缓冲区中。其命名的原因在于数据会被分散到指定缓冲区向量,或者从指定缓冲区向量中聚集数据。这种输入输出方法也称为向量 I/O(vector I/O)。与之不同,标准读写系统调用(read,write)可以称为线性I/O(linear I/O)。 与线性 I 阅读详情

1.Scatter  从一个Channel读取的信息分散到N个缓冲区中(Buufer).

2.Gather  将N个Buffer里面内容按照顺序发送到一个Channel.  

    Scatter/Gather功能是通道(Channel)提供的  并不是Buffer,

Scatter/Gather相关接口 类图

    ReadableByteChannel WritableByteChannel     接口提供了通道的读写功能

    ScatteringByteChannel  GatheringByteChannel接口都新增了两个以缓冲区数组作为参数的相应方法

   以FileChannel为例

   *Scatter

        /**
	 * Scatter
	 * <br>------------------------------<br>
	 * @param fileName
	 * @throws IOException
	 * @see FileChannel.read(java.nio.ByteBuffer[])
	 */
	private static void scatter(final String fileName) throws IOException {
		RandomAccessFile accessFile = new RandomAccessFile(fileName, "r");
		//获取文件通道
		FileChannel channel = accessFile.getChannel();
		//创建两个缓冲区
		ByteBuffer headBuffer = ByteBuffer.allocate(2);
		ByteBuffer bodyBuffer = ByteBuffer.allocate(1024);
		
		ByteBuffer[] allBuffers = new ByteBuffer[]{headBuffer, bodyBuffer};
		// headBuffer 前10个字节
		// bodyBuffer 剩下的 
		long n = channel.read(allBuffers);
		System.out.println("共读到多少字节:" + n);
		
		headBuffer.flip();
		//head缓冲区中的数据:qw
		System.out.println("head缓冲区中的数据:" + charset.decode(headBuffer));
		
		bodyBuffer.flip();
		//body缓冲区中的数据:ertyuiop
		System.out.println("body缓冲区中的数据:" + charset.decode(bodyBuffer));
		accessFile.close();
		channel.close();
	}

	/**
	 * Scatter2
	 * <br>------------------------------<br>
	 * @param fileName
	 * @throws IOException
	 * @see FileChannel.read(java.nio.ByteBuffer[], int, int)
	 */
	private static void scatter2(final String fileName) throws IOException {
		RandomAccessFile accessFile = new RandomAccessFile(fileName, "r");
		//获取文件通道
		FileChannel channel = accessFile.getChannel();
		//创建五个缓冲区
		ByteBuffer headBuffer = ByteBuffer.allocate(2);
		ByteBuffer bodyBuffer1 = ByteBuffer.allocate(3);
		ByteBuffer bodyBuffer2 = ByteBuffer.allocate(2);
		ByteBuffer bodyBuffer3 = ByteBuffer.allocate(2);
		ByteBuffer bodyBuffer4 = ByteBuffer.allocate(1);
		
		ByteBuffer[] allBuffers = new ByteBuffer[]{
				headBuffer, 
				bodyBuffer1, bodyBuffer2,
				bodyBuffer3, bodyBuffer4,};
		//0从那个缓冲区开始被使用    使用3个缓冲区
		//会使用 headBuffer,bodyBuffer1,bodyBuffer2
		long n = channel.read(allBuffers, 0, 3);
		
		System.out.println("共读到多少字节:" + n);
		
		headBuffer.flip();
		//head缓冲区中的数据:qw
		System.out.println("head缓冲区中的数据:" + charset.decode(headBuffer));
		
		bodyBuffer1.flip();
		//body1缓冲区中的数据:ert
		System.out.println("body1缓冲区中的数据:" + charset.decode(bodyBuffer1));
		
		bodyBuffer2.flip();
		//body2缓冲区中的数据:yu
		System.out.println("body2缓冲区中的数据:" + charset.decode(bodyBuffer2));
		
		bodyBuffer3.flip();
		//body3,没有数据
		System.out.println("body3缓冲区中的数据:" + charset.decode(bodyBuffer3));
		
		bodyBuffer4.flip();
		//body4没有数据
		System.out.println("body4缓冲区中的数据:" + charset.decode(bodyBuffer4));
		
		accessFile.close();
		channel.close();
	}
	
	/**
	 *
	 * <br>------------------------------<br>
	 * @param fileName
	 * @throws IOException
	 */
	private static void writeData(final String fileName, String data) throws IOException {
		RandomAccessFile accessFile = new RandomAccessFile(fileName, "rw");
		accessFile.writeBytes(data);
		accessFile.close();
	}
	private static Charset charset = Charset.forName("GBK");
	
	public static void main(String[] args) throws IOException {
		final String fileName = "D:/test.log";
		//先写入10个字节数据 以便测试 scatter模式
		writeData(fileName, "qwertyuiop");
		
		/**----------Scatter------------*/
		//read(java.nio.ByteBuffer[])
		scatter(fileName);
		
		//read(java.nio.ByteBuffer[], int, int)
		scatter2(fileName);
	}

*Gather

	/**
	 * gather
	 * <br>------------------------------<br>
	 * @param fileName
	 * @throws IOException 
	 * @see FileChannel#write(java.nio.ByteBuffer[])
	 */
	private static void gather(String fileName) throws IOException {
		RandomAccessFile accessFile = new RandomAccessFile(fileName, "rw");
		//获取文件通道
		FileChannel channel = accessFile.getChannel();
		//创建两个缓冲区
		ByteBuffer headBuffer = ByteBuffer.allocate(3);
		headBuffer.put("abc".getBytes());
		
		ByteBuffer bodyBuffer = ByteBuffer.allocate(1024);
		bodyBuffer.put("defg".getBytes());
		
		ByteBuffer[] allBuffers = new ByteBuffer[]{headBuffer, bodyBuffer};
		
		headBuffer.flip();
		bodyBuffer.flip();
		
		//将按allBuffers顺序  写入abcdefg
		long n = channel.write(allBuffers);
		
		System.out.println("共写入多少字节:" + n);
		
		accessFile.close();
		channel.close();
	}
	
	/**
	 * gather2
	 * <br>------------------------------<br>
	 * @param fileName
	 * @throws IOException 
	 * @see FileChannel#write(java.nio.ByteBuffer[], int, int)
	 */
	private static void gather2(String fileName) throws IOException {
		RandomAccessFile accessFile = new RandomAccessFile(fileName, "rw");
		//获取文件通道
		FileChannel channel = accessFile.getChannel();
		//创建两个缓冲区
		ByteBuffer headBuffer = ByteBuffer.allocate(3);
		ByteBuffer bodyBuffer1 = ByteBuffer.allocate(4);
		ByteBuffer bodyBuffer2 = ByteBuffer.allocate(20);
		ByteBuffer bodyBuffer3 = ByteBuffer.allocate(20);
		ByteBuffer bodyBuffer4 = ByteBuffer.allocate(20);
		
		headBuffer.put("abc".getBytes());
		bodyBuffer1.put("defg".getBytes());
		bodyBuffer2.put("bnbnbnb".getBytes());
		bodyBuffer3.put("zzz444".getBytes());
		
		ByteBuffer[] allBuffers = new ByteBuffer[]{
				headBuffer, 
				bodyBuffer1, bodyBuffer2,
				bodyBuffer3, bodyBuffer4,};
		
		headBuffer.flip();
		bodyBuffer1.flip();
		bodyBuffer2.flip();
		bodyBuffer3.flip();
		bodyBuffer4.flip();
		
		//将按allBuffers数组顺序使用两个缓冲区
		//0从哪开始
		//2使用几个
		//当前使用headBuffer  bodyBuffer1
		//最终写入abcdefg
		long n = channel.write(allBuffers, 0, 2);
		
		//应该返回7个字节
		System.out.println("共写入多少字节:" + n);
		
		accessFile.close();
		channel.close();
	}
	private static Charset charset = Charset.forName("GBK");
	
	public static void main(String[] args) throws IOException {
		final String fileName = "D:/test.log";
		/**----------Gather------------*/
		//FileChannel#write(java.nio.ByteBuffer[])
		gather(fileName);
		
		//FileChannel#write(java.nio.ByteBuffer[], int, int)
		gather2(fileName);
	}
window系统 dlib库安装 1. 安装visual studio 1.1. 安装vs2017或以上版本 1.2. 我们需要安装使用C++的桌面开发,且必须选上用于Cmake的Visual C++工具 1.3. 安装完成后,将D:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin 添加到环境变量PATH中 2 下载cmake文件,并添加环境变量 2.1 在c 阅读详情

相关推荐

sdc时钟约束2——多驱动时钟

sdc 多驱动时钟 master_clock

qq_40411444的博客 5529

Java NIO中的通道Channel(二)分散/聚集 Scatter/Gather

什么是Scatter/Gather scatter/gather指的在多个缓冲区上实现一个简单的I/O操作,比如从通道中读取数据到多个缓冲区,或从多个缓冲区中写入数据到通道; scatter(分散):指的是从通道中读取数据分散到多个缓冲区Buffer的过程,该过程会将每个缓存区填满,直至通道中无数据或缓冲区没有空间; gather(聚集):指的是将多个缓冲区Buffer聚集起来写入到通道的过...

weixin_34311757的博客 450

新手必看!Stata工具变量分析中的三大陷阱:如何正确解读LM统计量、CDW检验和Hansen J值

本文深度解析Stata工具变量分析中的三大核心检验:不可识别检验、弱IV检验和过度识别检验,帮助新手避开常见陷阱。详细解读LM统计量、CDW检验和Hansen J值的正确使用方法,提供实战案例和Stata操作指南,确保研究结论的可靠性。

weixin_29231027的博客 572

scatter/gather I/O

发散/汇聚映射 通用DMA框架还提供了一种特殊类型的流DMA映射机制–发散/汇聚映射。该机制允许一次为多个缓冲区创建DMA映射。其原型如下: int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction direction); 各参数含义如下: dev:设备数据结构...

申小白 3966

Simulink Test Sequence自动化测试实战:从Excel到模型验证

本文详细介绍了如何利用Excel和MATLAB脚本实现Simulink Test Sequence的自动化测试。通过设计结构化Excel模板管理测试数据,并调用Simulink Test API批量创建与执行测试用例,该方法能显著提升复杂模型单元测试的效率,便于集成到CI/CD流程,实现从数据到验证的全自动化。

weixin_29261711的博客 144

STM32 HAL库ADC+DMA配置详解:从CubeMX到实战调试

在嵌入式系统开发中,模数转换器(ADC)是实现传感器数据采集、信号处理等功能的基石。其工作原理是将连续的模拟信号转换为离散的数字量,为微控制器(MCU)提供可处理的数字信息。为了提升系统效率,直接存储器访问(DMA)技术被引入,它作为独立于CPU的数据搬运工,能在不占用CPU资源的情况下,自动完成外设与内存间的数据传输,从而解放CPU以执行更复杂的控制算法或通信任务。这种ADC与DMA的协同工作模式,对于实现高效、实时的数据流处理具有重要价值,广泛应用于电机控制、环境监测、音频处理等场景。本文聚焦于STM3

weixin_30698297的博客 408

(四)Scatter/Gather

一、简介 Java NIO开始支持scatter/gather,scatter/gather用于描述从Channel中读取或者写入到Channel的操作。 分散(scatter)从Channel中读取是指在读操作时将读取的数据写入多个buffer中。因此,Channel将从Channel中读取的数据“分散(scatter)”到多个Buffer中。 聚集(gather)写入Channel是指在...

daziyuanazhen的博客 621

AI量化投资开源平台——Qlib(微矿)的学习使用笔记(随缘更新)

Qlib 涵盖了量化投资的全过程,为用户的 AI 算法提供了高性能的底层基础架构,从框架设计上让用户可以更容易地应用 AI 算法来辅助解决量化投资的各个关键问题(例如 Alpha 预测,风险预测,市场动态性建模)。本文旨在记录一些面向初学者的基础内容。

in_void的博客 3133

NIO04——Scatter 和 Gather

 Java NIO 内置了 Scatter(分散器) 和 Gather(聚集器),Scatter 和 Gather 是从 Channel 中读取数据或者向 Channel 中写入数据的相关概念。  Channel 的分散(Scatter)读是指将一个 Channel 中的数据读取到多个 Buffer 中的读操作,即将这个 Channel 中的数据“分散”到多个 Buffer 中。  Channel...

如不來的博客 548

大模型实战—通义千问大模型微调

这个参数仅针对 llama 类型的模型结构,默认勾选的是 q_proj 和 v_proj,具体的名词不容易理解,我就不多说了,可以简单的认为是对模型的理解能力进行优化,一般这两个就够了。当这个值较高时,适应新任务的能力会增强,但是对基础模型的影响会比较大,有过拟合的风险,尤其是在数据量有限的情况下。为了方便测试,我在云环境也创建了一个镜像,相关的环境都配置好了,可以直接使用几个国内开源的大语言模型,比如清华智谱的ChatGLM3-6B、零一万物的Yi-34B,还有最近阿里云开源的Qwen1.5-32B。

7万+

Could not find a package configuration file provided by “boost_signals“

gmapping/slam_gmapping/gmapping/CMakeLists.txt:14 (find_package)问题在14行,注释该行。,该语句的用以为告诉项目Boost库文件所在。

weixin_72050316的博客 1027

Java NIO Scatter / Gather

Java NIO引入了scatter/gather机制,用于高效地处理通道数据的读写。Scattering read允许从单个通道读取数据并分散到多个缓冲区,适用于处理固定大小的数据部分,如消息的header和body。Gathering write则相反,它从多个缓冲区收集数据并写入单个通道,适用于处理可变大小的数据。这两种操作通过缓冲区数组实现,分别使用channel.read(bufferArray)和channel.write(bufferArray)方法。Scatter/gather在处理分段数据

Java的专栏 689

OpenClaw小白使用全攻略

OpenClaw全能技能解锁指南:从基础到进阶 摘要: 本文提供OpenClaw AI智能体的完整使用教程,帮助用户从安装后"不知道如何用"到熟练掌握核心功能。教程包含:1)控制台5大区域详解和3个必做初始化设置;2)文件管理、浏览器自动化、文档生成等5大基础功能实操,每个功能配有详细操作步骤、指令模板和效果演示;3)10+高频场景解决方案,如整理文件、搜集资料、写总结等;4)进阶技巧和常见问题解答。通过清晰的图文指引,即使电脑小白也能快速上手,实现办公自动化、提升工作效率。

通俗易懂学IT 3059

NIO之Scatter/Gather

Java NIO开始支持scatter/gather,scatter/gather用于描述从Channel中读取或者写入到Channel的操作。 **分散(scatter)**从Channel中读取是指在读操作时将读取的数据写入多个buffer中。因此,Channel将从Channel中读取的数据“分散(scatter)”到多个Buffer中。 **聚集(gather)**写入Channel是指在...

dream_follower的博客 317

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

NIO学习 - Scatter/Gather

Java NIO -Scatter/Gather Java NIO 开始支持scatter/gather,scatter/gather用于描述从Channel中读取或者写入到Channel的操作。 scatter/gather的 分散(scatter)从Channel中读取是指在读操作时将读取的数据写入多个buffer中。因此,Channel将从Channel中读取的数据“分散(scatter)”到多个Buffer中。 聚集(gather)写入Channel是指在写操作时将多个buffer的数据写入同一个C

zonkidd的博客 199

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

从NIO到netty(3) Scatter/Gather与selector

分散(scatter)从Channel中读取是指在读操作时将读取的数据写入多个buffer中。因此,Channel将从Channel中读取的数据“分散(scatter)”到多个Buffer中。 聚集(gather)写入Channel是指在写操作时将多个buffer的数据写入同一个Channel,因此,Channel 将多个Buffer中的数据“聚集(gather)”后发送到Channel。 sc...

m0_37139189的博客 237

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

NIO Channel Scatter/Gather 管道Pipe类

通道提供了一种被称为Scatter/Gather的重要新功能(有时也被称为矢量I/O)。Scatter/Gather是一个简单却强大的概念,它是指在多个缓冲区上实现一个简单的I/O操作。对于一个write操作而言,数据是从几个缓冲区按顺序抽取(称为gather)并沿着通道发送的。缓冲区本身并不需要具备这种gather的能力(通常它们也没有此能力)。该gather过程的效果就好比全部缓冲区...

dimei8552的博客 153

【译】Java NIO Scatter / Gather

Java NIO原生支持scatter和gather。Scatter/Gather是从channel中读取或者是向channel中写入时的概念。 一个scatter类型的reading操作,就是一次读操作中会读取多个buffer。 一个gather类型的writing操作,就是一次向channel中写入多个buffer。 在需要分别处理传输数据的各个部分的情况下,Scatter/Gather...

nickDaDa的博客 251

Java NIO Scatter/Gather

Scatter/Gather Java NIO中scatter/gather用于描述从Channel(译者注:Channel在中文经常翻译为通道)中读取或者写入到Channel的操作。 分散(scatter)从Channel中读取是指在读操作时将读取的数据写入多个buffer中。因此,Channel将从Channel中读取的数据“分散(scatter)”到多个Buffer中。 聚集(gather...

书香水墨 240

Netty学习笔记(5)——NIO中的Scatter/Gather机制

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> ...

江左煤郎的博客 562

Java NIO系列教程(四) Scatter/Gather

Java NIO开始支持scatter/gather,scatter/gather用于描述从Channel(译者注:Channel在中文经常翻译为通道)中读取或者写入到Channel的操作。 分散(scatter)从Channel中读取是指在读操作时将读取的数据写入多个buffer中。因此,Channel将从Channel中读取的数据“分散(scatter)”到多个Buffer中。 聚集(gath...

limeOracle的博客 139

NIO学习笔记(4) -- Scatter/Gather

NIO学习笔记(4) – Scatter/Gather ​ 分散(scatter)从 Channel 中读取是指在读操作时将读取的数据写入多个 buffer 中。因此,Channel 将从 Channel 中读取的数据 “分散(scatter)” 到多个 Buffer 中。 ​ 聚集(gather)写入 Channel 是指在写操作时将多个 buffer 的数据写入同一个 Channel,因此,C...

qq_38970428的博客 273
上一篇: NIO - Buffer缓冲区
下一篇: NIO - MappedByteBuffer
胸口碎大石_
博客等级 码龄17年 1154粉丝 82原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值