几种文件读写方式的性能比较

文件读写性能受到诸多因素的影响,其中缓冲区是不容忽视的因素

下面看几个示例来比较一下各种文件操作的性能对比

1、单字节拷贝

将一个37M的文件test1.txt读出来然后写入到dest.txt,实现文件的拷贝。
在这里插入图片描述
示例代码:

	@Test
	public void perByteOperation() {
		LOGGER.info("开始单字节单字节复制文件...");
		long start = System.currentTimeMillis();
		try (FileInputStream fis = new FileInputStream(TEST_PATH + "test1.txt");
		     FileOutputStream fos = new FileOutputStream(TEST_PATH + "dest.txt")) {
			int i;
			while ((i = fis.read()) != -1) {
				fos.write(i);
			}
		} catch (Exception e) {
			LOGGER.error("单字节单字节复制文件异常", e);
		}
		LOGGER.info("结束单字节单字节复制文件...,耗时:{}ms", System.currentTimeMillis() - start);
	}
[INFO ][2020/09/08 08:55:03][main] - 开始单字节单字节复制文件...
[INFO ][2020/09/08 08:57:31][main] - 结束单字节单字节复制文件...,耗时:148090ms

耗时148s,可怕!

2、采用100个字节的缓冲区

示例代码:

	@Test
	public void bufferOperationWith100() {
		LOGGER.info("开始带100字节缓冲区复制文件...");
		long start = System.currentTimeMillis();
		try (FileInputStream fis = new FileInputStream(TEST_PATH + "test1.txt");
		     FileOutputStream fos = new FileOutputStream(TEST_PATH + "dest.txt")) {
			byte[] buf = new byte[100];
			int len;
			while ((len = fis.read(buf)) != -1) {
				fos.write(buf, 0, len);
			}
		} catch (Exception e) {
			LOGGER.error("带100字节缓冲区复制文件", e);
		}
		LOGGER.info("开始带100字节缓冲区复制文件...,耗时:{}ms", System.currentTimeMillis() - start);
	}
[INFO ][2020/09/08 08:59:05][main] - 开始带100字节缓冲区复制文件...
[INFO ][2020/09/08 08:59:07][main] - 开始带100字节缓冲区复制文件...,耗时:2237ms

可见,增加了缓冲区之后,速度大大提高了。

3、采用BufferedStream

BufferedStream采用了 private static int DEFAULT_BUFFER_SIZE = 8192; 8Kb的缓冲区。
示例代码:

	@Test
	public void bufferStreamByteOperation() {
		LOGGER.info("开始带缓冲区复制文件...");
		long start = System.currentTimeMillis();
		try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(TEST_PATH + "test1.txt"));
		     BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(TEST_PATH + "dest.txt"))) {
			int i;
			while ((i = bis.read()) != -1) {
				bos.write(i);
			}
		} catch (Exception e) {
			LOGGER.error("带缓冲区复制文件文件异常", e);
		}
		LOGGER.info("开始带缓冲区复制文件...,耗时:{}ms", System.currentTimeMillis() - start);
	}
[INFO ][2020/09/08 09:01:18][main] - 开始带缓冲区复制文件...
[INFO ][2020/09/08 09:01:20][main] - 开始带缓冲区复制文件...,耗时:2350ms

为啥我们使用了缓冲流,没有明显提高呢?原因是虽然读取写入使用了缓冲流,但bos.write(i);方法是按单字节写入的,调用次数过多。

4、在BufferedStream基础上,写入的时候新增一个8KB的缓冲
	@Test
	public void bufferStreamBufferOperation() {
		LOGGER.info("bufferStreamBufferOperation开始带缓冲区复制文件...");
		long start = System.currentTimeMillis();
		try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(TEST_PATH + "test1.txt"));
		     BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(TEST_PATH + "dest.txt"))) {
			byte[] buf = new byte[8196];
			int i;
			while ((i = bis.read(buf)) != -1) {
				bos.write(buf, 0, i);
			}
		} catch (Exception e) {
			LOGGER.error("带缓冲区复制文件文件异常", e);
		}
		LOGGER.info("开始带缓冲区复制文件...,耗时:{}ms", System.currentTimeMillis() - start);
	}
[INFO ][2020/09/08 09:05:02][main] - bufferStreamBufferOperation开始带缓冲区复制文件...
[INFO ][2020/09/08 09:05:02][main] - 开始带缓冲区复制文件...,耗时:132ms
5、不采用缓冲流,只新增8KB的缓冲数组
	@Test
	public void streamBufferOperation() {
		LOGGER.info("streamBufferOperation开始带缓冲区复制文件...");
		long start = System.currentTimeMillis();
		try (FileInputStream fis = new FileInputStream(TEST_PATH + "test1.txt");
		     FileOutputStream fos = new FileOutputStream(TEST_PATH + "dest.txt")) {
			byte[] buf = new byte[8196];
			int i;
			while ((i = fis.read(buf)) != -1) {
				fos.write(buf, 0, i);
			}
		} catch (Exception e) {
			LOGGER.error("带缓冲区复制文件文件异常", e);
		}
		LOGGER.info("开始带缓冲区复制文件...,耗时:{}ms", System.currentTimeMillis() - start);
	}
[INFO ][2020/09/08 09:06:27][main] - streamBufferOperation开始带缓冲区复制文件...
[INFO ][2020/09/08 09:06:27][main] - 开始带缓冲区复制文件...,耗时:120ms
总结:

我们可以看到4,5花费的时间差不多,但我们推荐第4种方案。但在实际代码中每次需要读
取的字节数很可能不是固定的,有的时候读取几个字节,有的时候读取几百字节,这个时候有一个固定大小较大的缓冲,也就是使用 BufferedInputStream 和
BufferedOutputStream 做为后备的稳定的二次缓冲,就非常有意义了。

拓展:

DMA(直接内存访问),数据从磁盘经过总线直接发送到目标文件,无需经过内存和 CPU 进行数据中转,这种方式更快。

	/**
	 * @Description 采用的是DMA(直接内存访问)也就是数据从磁盘经过总线直接发送到目标
	 * 文件,无需经过内存和 CPU 进行数据中转:
	 * @author chenwb
	 * @date 2020/9/8 9:21
	 */
	@Test
	public void fileChannelOperation() throws IOException {
		LOGGER.info("fileChannelOperation开始复制文件...");
		long start = System.currentTimeMillis();
		FileChannel in = FileChannel.open(Paths.get(TEST_PATH + "test1.txt"), StandardOpenOption.READ);
		FileChannel out = FileChannel.open(Paths.get(TEST_PATH + "dest.txt"), StandardOpenOption.CREATE,
				StandardOpenOption.WRITE);
		in.transferTo(0, in.size(), out);
		LOGGER.info("结束复制文件...,耗时:{}ms", System.currentTimeMillis() - start);
	}
[INFO ][2020/09/08 09:22:30][main] - fileChannelOperation开始复制文件...
[INFO ][2020/09/08 09:22:30][main] - 结束复制文件...,耗时:48ms
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CH375的U盘读写模块功能概述: 该U 盘文件读写模块用于向嵌入式系统/单片机系统提供读写U 盘中文件数据的接口,基本不需要占用单片机系统的存储空间,最少只需要几个字节的RAM 和几百字节的代码。该模块基于CH375的U盘文件级子程序库设计,外围电路精简,性能价格比很高。 单片机可以通过USB总线HOST&DEVICE接口芯片CH375读写U 盘中的数据,虽然直接调用CH375的U 盘文件级子程序库读写U盘文件的效率更高,成本更低,但是该子程序库需要占用单片机系统的资源,大约5KB 程序空间和600 字节RAM 数据存储器,无法应用于某些资源有限的单片机系统。 CH375的U盘读写模块实物截图: CH375的U盘读写模块功能与特点: > 用于嵌入式系统/单片机读写U 盘、闪盘、闪存盘、USB 移动硬盘、USB 读卡器等。 > 支持符合USB 相关规范基于Bulk-Only 传输协议的各种U 盘/闪存盘/外置硬盘。 > 支持文件系统FAT12 和FAT16 及FAT32,如果需要支持FAT32 请看本文后面的说明。 > 提供工具程序,只要连接计算机USB 端口,就可以随时升级模块,随时设置模块。 > 支持小端格式和大端格式的数据字节顺序,适用于绝大多数单片机系统。 > 文件操作功能:搜索、新建、删除、读写数据,查询和修改信息等。 > 读写模式:高速的扇区模式、方便的字节模式、简化的数据流模式。 > 提供3 种硬件以适应不同的I/O 接口:标准版、串口版、低电压版。 > 提供多种软件供随时下载到模块硬件中,通过多种软硬件组合支持各种不同的I/O 接口。 > 模块具有简单的自动演示功能,提供串口连接方式下的计算机端的演示工具。 CH375的U盘读写模块 PCB截图:
扬皓文件批量处理器(GFileBat)的强大综合工具,包括十几种方式批量重命名文件,批量修改文件内容、属性、时间、快捷方式信息、音乐标签,批量创建文件文件夹、智能归档,批量分割和合并文件,批量下载网络图片、批量转换图片尺寸和格式、截取区域和插入水印等等,总有 28 批量处理栏目。 扬皓文件批量处理器(GFileBat)特点: ● 以编号递进的数值序列修改文件名 ● 替换文件名中某字符为另外字符(可使用正则) ● 删除文件名中某字符(或位置)的左右边字符 ● 在文件名某位置插入字符 ● 清除文件名中特定字符集 ● 转换文件名格式 ● 文件名列表对应改名 ● 以音乐曲目标签信息修改文件名 ● 以文件时间修改文件名 ● 以文本文件中某指定内容修改文件名 ● ........ 以上批量改名功能均可以在FTP上批量操作。 全新设计,致力简洁,性能提升,功能更强(功能对比请参考原灵者更名)。 主打批量处理功能,批量处理功能中主打批量改名,总有几十项批量处理功能。其余全是配套功能。 ◆ 支持FTP远程批量操作,支持与本地列表混合操作 ◆ 支持各种用途【元符】插入组合 ◆ 支持多编码(ANSI、Utf-8,Unicode)读写文本文件 ◆ 支持随意拖动调整文件位置 ◆ 支持内置查看器快速查看文件内容(文本文件、音视频等媒体、图片文件等等) ◆ 支持导入和导出文件列表 ◆ 支持多种过滤搜索,包括导入文本文件文件名列表搜索目录 ◆ 支持内置各种辅助处理工具 ◆ 支持方案保存和加载(批量处理栏目) ◆ 支持更多(很多都忘了,自己体验吧,同时功能还在不断扩展和完善)。   水淼揚皓文件批量处理器  v1.71正式版更新: 修正了一个上次更新导致的工具栏图标响应错位的问题
FastCopy 是 Windows 平台上最快的文件拷贝、删除软件,它支持 UNICODE 和超过 MAX_PATH (260 个字符)的文件路径名。由于其功能强劲,性能优越,一时间便超越相同类型的所有其他软件。由于该软件十分小巧,你甚至可以在打开后,直接将安装目录中的文件复制到任何可移动存储设备中,方便携带,随取随用。 FastCopy 会根据源目录和目标目录是否在相同的硬盘(或 SSD)中,自动选择不同的方法。 不同的硬盘:读取和写入分别由单独的线程并行处理。 相同的硬盘:读取处理,直到大的缓冲区填满为止。当大缓冲区被填满时,开始写入并批量处理。 FastCopy 在不使用操作系统缓存的情况下处理读取/写入,不会影响其它应用程序运行时的速度。 FastCopy 可实现接近于设备限制的读取/写入性能。 FastCopy软件功能 1.Windows最快的文件复制,备份与删除工具。 2.您还可以复制(与删除)只能由UNICODE表示的文件名与超过MAX_PATH(260个字符)的文件。 3.读/写/验证独自的线程操作与异步I / O与直接I / O使性能接近设备的极限。 4.可以指定包含/排除过滤器(UNIX通配符格式)。 5.由于仅使用Win32API而不使用MFC等框架,所以它轻巧,紧凑且易于操作。 FastCopy软件特点 1.完全支持拖曳操作,支持拖曳多个文件到来源中。 2.支持外壳组合,方便使用右键菜单直接复制文件。 3.支持三种不同的HDD模式。 4.内建多种人性化的操作模式。 5.支持过滤,可以使用通配符。 6.支持任务管理。 7.支持命令行操作。 8.软件十分小巧,甚至可以在安装完后,直接将安装目录中的文件覆盖到任何可移动存储设备中,方便携带,随取随用。 9.易于使用,可以充分挖掘文件系统与硬盘的传输能力。 10.支持计数与计时,在很多实用的硬盘传输速率的评测中,FastCopy 成了不二之选。 FastCopy软件优势 1.FastCopy 可以在不使用系统缓存的情况下处理读取/写入,不会影响其它应用程序运行时的速度。 2.FastCopy 可以实现接近于设备限制的读取/写入性能。 3.FastCopy 可以指定包含/排除过滤器(UNIX 通配符样式)。 4.FastCopy 运行快、不占资源。 所有的复制操作都是通过“从介质(硬盘)读数据→写入数据→从缓存中读出→向介质(硬盘)写入数据”这几项步骤来完成的,并且这些步骤都是多个线程同时进行的,如果线程之间的协同运作不够完美,那速度就会大打折扣,有些线程忙得要命,而有些却必须等待,FASTCOPY就是优化了它们之间的工作顺序,大大提高了速度。 FastCopy软件主要特点 ├—FastCopy 是免费开源Windows上最快的复制/备份软件。 ├—支持UNICODE和超过MAX_PATH(260字符)的文件路径名。 ├—使用多线程读/写/校验,重叠IO,直接IO,从而实现设备最高读写性能。 ├—可以使用 UNIX通配符 样式的 包含/排除 筛选器。 ├—运行速度快,不占资源,因为仅使用 Win32 API 和 C 运行时设计,没有使用 MFC。 为什么需要第三方文件复制软件? 相比Windows自带的文件复制/粘贴方式,第三方文件复制软件提供了:更高性能、更多的功能、更佳体验。它们的优化原理如下: 缓存机制:第三方文件复制软件,经常标榜“具备 XX MB 的写入缓存”。其原理是,在复制/移动的过程中,Windows会先读取一部分数据到缓存中;再从缓存中写入到新介质。其实,Windows 复制文件时,默认也开启了缓存机制,只是无法设置缓存大小。由于Windows默认的缓存太小,导致读取和转移这两过程基本都是同时进行,很容易出现瓶颈,致使“Windows复制文件快不起来”。而第三方文件复制软件会开辟一块更大的缓存空间,并把设置权重新交给用户。
该软件无论在 Windows XP还是在Windows 7都能获得比系统自带的复制功能要快20%~120%的性能提升。根据官方的视频显示其不仅比Windows 7自带的文件复制功能要快,甚至还比目前国外流行的TeraCopy和SuperCopier还要快得多。这种高效率的文件复制功能对目前越来越多和越来越大的硬盘占用容量的文件用户来说是非常实用的工具。 ExtremeCopy Pro是一款Windows文件复制移动增强软件,它会根据硬件和系统资源自动优化文件复制和移动速度,据软件官方介绍,它比Windows 自身的复制移动速度快20%到120%,免费是针对大文件较为明显。而且ExtremeCopy使用方便,如果你愿意,可以直接使用ExtremeCopy来接管Windows自身的复制移动功能。 ExtremeCopy 可以支持 XP~Windows 8,支持32与64位系统,可以非常有效地提高文件复制/移动的速度和稳定性,大大减小复制过程中产生错误的可能性。官方称其能让你获得比原系统的复制功能高达 20%~120% 的性能提升!(对于体积巨大的文件,或者文件数量巨大的文件夹效果最为明显)。并且在复制期间还能大大减小CPU的占用率,提高电脑的响应速度。 ExtremeCopy Pro 2.3.4 复制文件过程中可以暂停或跳过文件,经测试可以用 ExtremeCopy 复制局域网上的 NAS 网络文件,而且向左和向下的箭头还能看到更多有用的信息。 在安装软件之后,ExtremeCopy 可以取代 Windows 的资源管理器的自带复制/移动功能,使其成为系统默认的复制、剪切/粘贴工具。你依然可以跟往常一样右键复制、剪切/粘贴,或者使用 Ctrl+C、Ctrl+X / Ctrl+V 键盘快捷键进行操作,系统会直接调用 ExtremeCopy 来进行更高速稳定的文件复制/移动操作,非常方便。如果对于某些文件你喜欢使用 Win 自带的复制功能而不时 ExtremeCopy,那么在右键菜单中你只需选择 “Windows 粘贴” 即可。当然,你可以随时在软件配置里设置是否让 ExtremeCopy 成为系统的默认复制工具。 我们都知道,如果你想将电脑上不同路径的多个文件(夹)复制到一处,或者将一个文件(夹)复制到多个不同文件夹去,那么往往需要复制粘贴好几次才行。ExtremeCopy 则可以让你一次指定多个源文件(夹)和多个目标文件夹,你可以非常灵活地一次完成全部的复制移动操作!对于有此类特殊需求的用户可以节省大量的时间。 譬如你有D:\音乐,E:\电影两个文件夹,想将它们两分别同时复制到移动硬盘F:\和U盘G:\上,那么只需将音乐和电脑的文件夹拖放到在源文件框上,然后将移动硬盘和U盘的文件夹拖放到目标文件夹框中,即可一次完成所有工作。而且ExtremeCopy 会自动将任务进行排序,完成一项再做下一项,不会同时读写移动硬盘造成复制过程变得缓慢。 ExtremeCopy 可以支持通配符,譬如你的某个文件夹里面有着各种各样格式的文件,而现在只希望将其中全部的 MKV 和 AVI 视频拷贝到移动硬盘,那么你只需将文件夹拖放到源文件框里面,点选该文件夹后,按下“过滤”按钮即可指定「通配符」。如输入 *.mkv,*.avi 则可以将这两种文件全部筛选出来。对于这个已经设定了“过滤”的文件夹,在复制或移动时,只会对 mkv 和 avi 文件有效,其他的文件均不会被复制或移动。 当然,这不只是可以用来过滤扩展名,文件名也能通过这个功能来过滤,而且除了*号之外,还能支持?号进行匹配。譬如 iplaysoft* 或者 pic??.jpg,前者可以匹配开头的任意数量字符文件名,后者两个问号则只能匹配2个字母(如pic01.jpg / picab.jpg),总之,善用通配符可以让你的复制过程变得非常方便快捷。这个有时用来整理混乱的文件夹时很有作用。 ExtremeCopy Pro 对于目前越来越巨大的硬盘容量,以及越来越巨大的文件体积,ExtremeCopy 这种能真正提高文件复制、移动效率的软件确实非常实用!不但可以提高文件拷贝的速度,也会大大减少文件传输出错的几率,而且独有的多文件夹复制移动以及通配符的支持也能让它变得更加灵活方便。对于有更高端需求的朋友,还可以让 ExtremeCopy 在执行复制/移动任务完成之后再执行指定的命令行/批处理对文件进行再加工 (譬如调用 WinRAR 解压缩文件等/下图底部可以看到)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值