C# FileStream实现大文件复制
作者:kone666 发布时间:2021-06-14 11:00:53
标签:C#,FileStream,文件复制
FileStream缓冲读取和写入可以提高性能。FileStream读取文件的时候,是先将流放入内存,经Flush()方法后将内存中(缓冲中)的数据写入文件。如果文件非常大,势必消耗性能。特封装在FileHelper中以备不时之需。
参考文章:C# FileStream复制大文件。将该文章中提供的代码稍作修改,原文中进行了强制类型转换,如果文件很大,比如4G,就会出现溢出的情况,复制的结果字节丢失严重,导致复制文件和源文件大小不一样。这里修改的代码如下:
public static class FileHelper
{
/// <summary>
/// 复制大文件
/// </summary>
/// <param name="fromPath">源文件的路径</param>
/// <param name="toPath">文件保存的路径</param>
/// <param name="eachReadLength">每次读取的长度</param>
/// <returns>是否复制成功</returns>
public static bool CopyFile(string fromPath, string toPath, int eachReadLength)
{
//将源文件 读取成文件流
FileStream fromFile = new FileStream(fromPath, FileMode.Open, FileAccess.Read);
//已追加的方式 写入文件流
FileStream toFile = new FileStream(toPath, FileMode.Append, FileAccess.Write);
//实际读取的文件长度
int toCopyLength = 0;
//如果每次读取的长度小于 源文件的长度 分段读取
if (eachReadLength < fromFile.Length)
{
byte[] buffer = new byte[eachReadLength];
long copied = 0;
while (copied <= fromFile.Length - eachReadLength)
{
toCopyLength = fromFile.Read(buffer, 0, eachReadLength);
fromFile.Flush();
toFile.Write(buffer, 0, eachReadLength);
toFile.Flush();
//流的当前位置
toFile.Position = fromFile.Position;
copied += toCopyLength;
}
int left = (int)(fromFile.Length - copied);
toCopyLength = fromFile.Read(buffer, 0, left);
fromFile.Flush();
toFile.Write(buffer, 0, left);
toFile.Flush();
}
else
{
//如果每次拷贝的文件长度大于源文件的长度 则将实际文件长度直接拷贝
byte[] buffer = new byte[fromFile.Length];
fromFile.Read(buffer, 0, buffer.Length);
fromFile.Flush();
toFile.Write(buffer, 0, buffer.Length);
toFile.Flush();
}
fromFile.Close();
toFile.Close();
return true;
}
}
测试代码:
class Program
{
static void Main(string[] args)
{
Stopwatch watch = new Stopwatch();
watch.Start();
if (FileHelper.CopyFile(@"D:\安装文件\新建文件夹\SQLSVRENT_2008R2_CHS.iso", @"F:\SQLSVRENT_2008R2_CHS.iso", 1024 * 1024 * 5))
{
watch.Stop();
Console.WriteLine("拷贝完成,耗时:" + watch.Elapsed.Seconds+"秒");
}
Console.Read();
}
}
结果:
MD5校验结果:
文件: D:\安装文件\新建文件夹\SQLSVRENT_2008R2_CHS.iso
大小: 4662884352 字节
修改时间: 2010年9月3日, 10:41:26
MD5: D2BC1D35D987CC6CB8401BFB0A1E1BC9
SHA1: 0EEFF017B21635DF33F33C47E31E911CB23390F7
CRC32: 55AC3C56文件: F:\SQLSVRENT_2008R2_CHS.iso
大小: 4662884352 字节
修改时间: 2013年9月29日, 10:51:39
MD5: D2BC1D35D987CC6CB8401BFB0A1E1BC9
SHA1: 0EEFF017B21635DF33F33C47E31E911CB23390F7
CRC32: 55AC3C56
来源:https://blog.csdn.net/kone0611/article/details/80999406


猜你喜欢
- 开篇JDBC类型与Java类型并不是完全一一对应的。所以在PreparedStatement绑定参数的时候需要把Java类型转为JDBC类型
- 1. 为什么要进行参数校验在后端进行工作时,需要接收前端传来的数据去数据库查询,但是如果有些数据过于离谱,我们就可以直接把它pass掉,不让
- @JsonInclude(JsonInclude.Include.NON_NULL)不起作用记录一下使用@JsonInclude(JsonI
- 大家使用Android的原生UI都知道,Android的Activity跳转就是很生硬的切换界面。其实Android的Activity跳转可
- 首先我们定义一个可以在运行时动态的找出项目的路径WebAppRootKey,这么做的原因是为了在后面配置log4j输出文件路径的时候能随心配
- 首先让大家有个全局的认识,直接上个项目,看看仅仅通过这几行代码,竟然就能完成如此强悍的功能。下篇再仔细讲讲为什么要这么写。效果图:实现了三个
- 本文实例讲述了Android开发之获取LayoutInflater对象的方法。分享给大家供大家参考,具体如下:在写Android程序时,有时
- 本文是利用C# 实现FTP客户端的小例子,主要实现上传,下载,删除等功能,以供学习分享使用。思路:通过读取FTP站点的目录信息,列出对应的文
- 在2020.1.1版本之前IDEA pom文件导包是这样的最近新装新版本IDEA之后,这个图标没有了,对于习惯旧操作没有图标了还真不习惯。就
- Java读取json数据并存入数据库1. pom依赖<dependency> &nbs
- 本文主要是对Handler和消息循环的实现原理进行源码分析,如果不熟悉Handler可以参见博文《详解Android中Handler的使用方
- DataGridView是Visual Studio中一个最重要的数据控件。它可以应用在大多数场合,功能强大,使用灵活。本文要重点介绍一下,
- 本文实例讲述了Android实现点击AlertDialog上按钮时不关闭对话框的方法。分享给大家供大家参考。具体如下:开发过程中,有时候会有
- 目录一、什么是RPC?二、实现RPC需要解决那些问题?1. 约定通信协议格式2. 序列化方式3. TCP粘包、拆包4. 网络通信框架的选择三
- 本文主要介绍了spring-boot-maven-plugin报红解决方案,亲测有效,具体如下:<?xml version="
- 嗯,就是BASE64,不用多想,本来计划是要跟上一篇字符串压缩一起写的,用来实现将一个文件可以用json或者text等方式进行接口之间的传输
- springBoot使用事物比较简单,在Application启动类s上添加@EnableTransactionManagement注解,然
- ExecutorsExecutors 是一个Java中的工具类. 提供工厂方法来创建不同类型的线程池.从上图中也可以看出, Executor
- 最近公司要求开发工具要用Idea,作为一个eclipse的老员工,记录一下Idea中遇到的坑刚开始用Idea从Git上导入一个项目时,遇到了
- 一、实现了Aware的接口Spring中有很多继承于aware中的接口,这些接口到底是做什么用到的,下面我们就一起来看看吧。Aware 接口