warensoft 我是科学家

Warensoft 我是科学家

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 

C#实现大文件拷贝

warensoft 中科院计算所培训中心

 

以前的Blog中提到过如何利用FileStream实现文件拷贝,作法是利用FileStream将文件整个加载到内存中的Byte[]中,然后再这个数组直接利用FileStream写入到另外一个位置上,这么做有以下几个问题:

Ø         文件不能太大,文件太大,会占用过多内存,会导致系统内存不足

Ø         整个文件拷贝会无法精确查看拷贝进度

下面我们利用FileStream实现大文件的分块拷贝功能,并且显示出拷贝进度

大家如何有什么问题请给我发邮件:warensoft@163.com

本文的代码下载地址:https://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;

}

 

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();

}



posted on 2010-08-05 17:02  王宇 warensoft  阅读(2799)  评论(5编辑  收藏  举报