概述
C#实现大文件拷贝
warensoft 中科院计算所培训中心
以前的Blog中提到过如何利用FileStream实现文件拷贝,作法是利用FileStream将文件整个加载到内存中的Byte[]中,然后再这个数组直接利用FileStream写入到另外一个位置上,这么做有以下几个问题:
Ø 文件不能太大,文件太大,会占用过多内存,会导致系统内存不足
Ø 整个文件拷贝会无法精确查看拷贝进度
下面我们利用FileStream实现大文件的分块拷贝功能,并且显示出拷贝进度
大家如何有什么问题请给我发邮件:warensoft@163.com
本文的代码下载地址:http://files.cnblogs.com/warensoft/FileCopy.rar
1. 建立一个Window应用程序,如下图所示:
2. 在界面上添加控件,如下图所示:
上面两个按钮,分别用来设置要打开的原文件,以及要保存到的位置,它们的Click事件的代码对应如下:


///
/// 用于打开源文件
///
///
///
private void button1_Click( object sender, EventArgs e)
{
OpenFileDialog of = new OpenFileDialog();
of.ShowDialog();
this .textBox1.Text = of.FileName;
}
///
/// 用于设置保存文件的位置
///
///
///
private void button2_Click( object sender, EventArgs e)
{
SaveFileDialog sf = new SaveFileDialog();
sf.ShowDialog();
this .textBox2.Text = sf.FileName;
}
/// 用于打开源文件
///
///
///
private void button1_Click( object sender, EventArgs e)
{
OpenFileDialog of = new OpenFileDialog();
of.ShowDialog();
this .textBox1.Text = of.FileName;
}
///
/// 用于设置保存文件的位置
///
///
///
private void button2_Click( object sender, EventArgs e)
{
SaveFileDialog sf = new SaveFileDialog();
sf.ShowDialog();
this .textBox2.Text = sf.FileName;
}
3.
添加Copy按钮的Click事件,该代码为大文件拷贝的核心代码,其主要过程就是利用FileStream读一点到内存,再利用FileStream写一点到文件,只要没有读完,那么前面这个过程就不断的重复,其代码如下所示:


private
void
button3_Click(
object
sender, EventArgs e)
{
Thread thread = null ;
// 为了不让界面死掉,要将该操作放在一个线程中
thread = new Thread
(
() =>
{
// 告诉系统不去检测非法的跨线程调用
CheckForIllegalCrossThreadCalls = false ;
// 创建一个文件流指向源文件
FileStream fsRead = new FileStream( this .textBox1.Text, FileMode.Open);
// 创建一个文件流指向目标文件
FileStream fsWrite = new FileStream( this .textBox2.Text, FileMode.Create);
// 记录一下该文件的长度
long fileLength = fsRead.Length;
// 定义一个1M的缓冲区
byte [] buffer = new byte [ 1024 * 1024 ];
// 先读取一次,并且将读取到的真正内容长度记录下来
int readLength = fsRead.Read(buffer, 0 , buffer.Length);
// 用来记录已经将多少内容写入到了文件中
long readCount = 0 ;
// 只要读取到的内容不为0就接着读
while (readLength != 0 )
{
// 将前面已经读取到内存中的数据写入到文件中
fsWrite.Write(buffer , 0 ,readLength);
// 已经读取的数量累加
readCount += readLength;
// 计算已经读取的数据百分比
int percentage = ( int )( readCount * 100 / fileLength);
this .progressBar1.Value = percentage;
// 进行下一次读取
readLength = fsRead.Read(buffer, 0 , buffer.Length);
}
fsRead.Close();
fsWrite.Close();
// 清空缓冲区
buffer = null ;
// 回收一下内存
GC.Collect();
thread.Abort();
}
);
thread.Start();
}
{
Thread thread = null ;
// 为了不让界面死掉,要将该操作放在一个线程中
thread = new Thread
(
() =>
{
// 告诉系统不去检测非法的跨线程调用
CheckForIllegalCrossThreadCalls = false ;
// 创建一个文件流指向源文件
FileStream fsRead = new FileStream( this .textBox1.Text, FileMode.Open);
// 创建一个文件流指向目标文件
FileStream fsWrite = new FileStream( this .textBox2.Text, FileMode.Create);
// 记录一下该文件的长度
long fileLength = fsRead.Length;
// 定义一个1M的缓冲区
byte [] buffer = new byte [ 1024 * 1024 ];
// 先读取一次,并且将读取到的真正内容长度记录下来
int readLength = fsRead.Read(buffer, 0 , buffer.Length);
// 用来记录已经将多少内容写入到了文件中
long readCount = 0 ;
// 只要读取到的内容不为0就接着读
while (readLength != 0 )
{
// 将前面已经读取到内存中的数据写入到文件中
fsWrite.Write(buffer , 0 ,readLength);
// 已经读取的数量累加
readCount += readLength;
// 计算已经读取的数据百分比
int percentage = ( int )( readCount * 100 / fileLength);
this .progressBar1.Value = percentage;
// 进行下一次读取
readLength = fsRead.Read(buffer, 0 , buffer.Length);
}
fsRead.Close();
fsWrite.Close();
// 清空缓冲区
buffer = null ;
// 回收一下内存
GC.Collect();
thread.Abort();
}
);
thread.Start();
}
转载于:https://www.cnblogs.com/warensoft/archive/2010/08/05/1793349.html
最后
以上就是精明溪流为你收集整理的C# 大文件拷贝的全部内容,希望文章能够帮你解决C# 大文件拷贝所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复