C#复制文件显示进度
JR.Zhang 人气:0复制文件显示进度实际上就是文件流来复制文件,并在每一块文件复制后,用进度条来显示复制情况。
一、本实例中主要是以线程和委托的方式,在使用Filestream类对文件进行复制的同时,使用ProgressBar来显示文件复制进度,下面对本实例中用到的关键技术进行讲解。
(1) 线程构造函数
该构造函数主要初始化Thread类的新实例。语法格式如下:
public Thread(ThreadStart start);
参数说明:
start:ThreadStart委托,它表示线程开始执行时要调用的方法。
(2) 委托
在拥有此控件的基础窗口句柄的线程上执行指定的委托。语法格式如下:
public object Invoke(Delegate method);
参数说明:
1method:包含要在控件的线程上下文中调用的方法的委托。
2返回值:正在被调用的委托的返回值,或者如果委托没有返回值,则为空引用。
二、下面是程序的设计过程
(1)在VS中新建一个窗体应用程序,并将其命名为FileCopyPlan。
(2)更改默认窗体Form1的Name属性为Frm_Main,在窗体中添加一个OpenFileDialog控件用来选择源文件,添加一个FolderBrowserDialog控件,用来选择文件保存路径,添加两个TextBox控件,分别用来显示源文件和目的文件的路径,添加3个Button控件,分别用来选择源文件和目的文件的路径,以及实现文件的路径功能;添加一个ProgressBar控件用来显示进度条。
(3)程序的后台代码以及注释如下:
public partial class Frm_Main : Form { public Frm_Main() { InitializeComponent(); } private System.Threading.Thread thdAddFile; //创建一个线程 private string str = ""; FileStream FormerOpen;//实例化FileStream类 FileStream ToFileOpen;//实例化FileStream类 private void button1_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialog() == DialogResult.OK)//打开文件对话框 textBox1.Text = openFileDialog1.FileName;//获取源文件的路径 } private void button2_Click(object sender, EventArgs e) { if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)//打开文件夹对话框 textBox2.Text = folderBrowserDialog1.SelectedPath;//获取目的文件的路径 } private void button3_Click(object sender, EventArgs e) { if (textBox1.Text.Length == 0 || textBox2.Text.Length == 0) { MessageBox.Show("请选择原文件路径或目的文件路径。"); return; } str = textBox1.Text;//记录源文件的路径 str = "\\" + str.Substring(str.LastIndexOf('\\') + 1, str.Length - str.LastIndexOf('\\') - 1);//获取源文件的名称 thdAddFile = new Thread(new ThreadStart(SetAddFile));//创建一个线程 thdAddFile.Start();//执行当前线程 } public delegate void AddFile();//定义委托 /// <summary> /// 在线程上执行委托 /// </summary> public void SetAddFile() { this.Invoke(new AddFile(RunAddFile));//在线程上执行指定的委托 } /// <summary> /// 对文件进行复制,并在复制完成后关闭线程 /// </summary> public void RunAddFile() { CopyFile(textBox1.Text, textBox2.Text + str, 1024, progressBar1);//复制文件 thdAddFile.Abort();//关闭线程 } /// <summary> /// 文件的复制 /// </summary> /// <param FormerFile="string">源文件路径</param> /// <param toFile="string">目的文件路径</param> /// <param SectSize="int">传输大小</param> /// <param progressBar="ProgressBar">ProgressBar控件</param> public void CopyFile(string FormerFile, string toFile, int SectSize, ProgressBar progressBar1) { progressBar1.Value = 0;//设置进度栏的当前位置为0 progressBar1.Minimum = 0;//设置进度栏的最小值为0 FileStream fileToCreate = new FileStream(toFile, FileMode.Create);//创建目的文件,如果已存在将被覆盖 fileToCreate.Close();//关闭所有资源 fileToCreate.Dispose();//释放所有资源 FormerOpen = new FileStream(FormerFile, FileMode.Open, FileAccess.Read);//以只读方式打开源文件 ToFileOpen = new FileStream(toFile, FileMode.Append, FileAccess.Write);//以写方式打开目的文件 int max = Convert.ToInt32(Math.Ceiling((double)FormerOpen.Length / (double)SectSize));//根据一次传输的大小,计算传输的个数 progressBar1.Maximum = max;//设置进度栏的最大值 int FileSize;//要拷贝的文件的大小 if (SectSize < FormerOpen.Length)//如果分段拷贝,即每次拷贝内容小于文件总长度 { byte[] buffer = new byte[SectSize];//根据传输的大小,定义一个字节数组 int copied = 0;//记录传输的大小 int tem_n = 1;//设置进度栏中进度块的增加个数 while (copied <= ((int)FormerOpen.Length - SectSize))//拷贝主体部分 { FileSize = FormerOpen.Read(buffer, 0, SectSize);//从0开始读,每次最大读SectSize FormerOpen.Flush();//清空缓存 ToFileOpen.Write(buffer, 0, SectSize);//向目的文件写入字节 ToFileOpen.Flush();//清空缓存 ToFileOpen.Position = FormerOpen.Position;//使源文件和目的文件流的位置相同 copied += FileSize;//记录已拷贝的大小 progressBar1.Value = progressBar1.Value + tem_n;//增加进度栏的进度块 } int left = (int)FormerOpen.Length - copied;//获取剩余大小 FileSize = FormerOpen.Read(buffer, 0, left);//读取剩余的字节 FormerOpen.Flush();//清空缓存 ToFileOpen.Write(buffer, 0, left);//写入剩余的部分 ToFileOpen.Flush();//清空缓存 } else//如果整体拷贝,即每次拷贝内容大于文件总长度 { byte[] buffer = new byte[FormerOpen.Length];//获取文件的大小 FormerOpen.Read(buffer, 0, (int)FormerOpen.Length);//读取源文件的字节 FormerOpen.Flush();//清空缓存 ToFileOpen.Write(buffer, 0, (int)FormerOpen.Length);//写放字节 ToFileOpen.Flush();//清空缓存 } FormerOpen.Close();//释放所有资源 ToFileOpen.Close();//释放所有资源 if (MessageBox.Show("复制完成") == DialogResult.OK)//显示"复制完成"提示对话框 { progressBar1.Value = 0;//设置进度栏的当有位置为0 textBox1.Clear();//清空文本 textBox2.Clear(); str = ""; } } }
(4) 程序运行结果如图所示:
加载全部内容