// 主程序
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using System.IO; namespace WFcopyFile { static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } class DoWorks { //定一个一个委托 public delegate void CopyFileHandler(long lngPosition, long LngCount); //定义一个事件(很重要),这个事件将被主线程捕捉,并对主线程的内容进行更改,比如:进度条。 public event CopyFileHandler CopyFileEvent; //定义两个字符串变量,sFile表示源文件,tFile表示目标文件,当然,这个可以使用属性的方式,这个为了简单明了,直接使用共有变量。 public System.String sFile; public System.String tFile; //这个就是工作线程使用到的方法了。 public void CopyFile() { //定义一个字节数组,用来缓存从源文件读到的字节流。 byte[] fb = new byte[2048]; //定义当前已读字节数,用于主线程更新界面。 long lngPosition = 0; //源文件流 FileStream sfs = new FileStream(sFile, System.IO.FileMode.Open, System.IO.FileAccess.Read); //二进制文件读取器 BinaryReader br = new BinaryReader(sfs); br.BaseStream.Seek(0, System.IO.SeekOrigin.Begin); if (File.Exists(tFile)) File.Delete(tFile); //目标文件流 FileStream tfs = new FileStream(tFile, System.IO.FileMode.CreateNew, System.IO.FileAccess.Write); //二进制文件写入器 BinaryWriter bw = new BinaryWriter(tfs); //源文件的大小 long positionLength = sfs.Length; int k = 10000; //当读到的字节数小于2048,表示已经读到文件流的末尾了。停止读取 while (k >= 2048) { k = br.Read(fb, 0, fb.Length); bw.Write(fb); lngPosition += k; //触发事件(关键),参数:1、表示当前共读取了多少,2、表示文件的长度 CopyFileEvent(lngPosition, positionLength); } tfs.Flush(); bw.Close(); br.Close(); tfs.Close(); sfs.Close(); } } }
子程序:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; namespace WFcopyFile { public partial class Form1 : Form { private DoWorks dw = new DoWorks(); public Form1() { InitializeComponent(); Control.CheckForIllegalCrossThreadCalls = false; } private void button1_Click(object sender, EventArgs e) { this.openFileDialog1.ShowDialog(); //这两个公有变量一定要赋值,因为这次主要演示目的,一些判断及异常处理省略了。 if(dw.sFile=="") dw.sFile = "c:\\new.pdf"; dw.tFile = "c:\\newFile.pdf"; //这个是关键,定义事件的处理方法。 订阅事件 将事件处理程序绑定到事件上,取消订阅用 -= 号 dw.CopyFileEvent += new WFcopyFile.DoWorks.CopyFileHandler(this.ChgProgress); //定义新线程。 Thread t = new Thread(new ThreadStart(dw.CopyFile)); //启动线程 t.Start(); } private void ChgProgress(long k, long count) { this.progressBar1.Maximum = (int)count; this.progressBar1.Minimum = 0; this.progressBar1.Value = (int)k; this.label1.Text = count.ToString(); this.label2.Text = k.ToString(); } private void openFileDialog2_FileOk(object sender, CancelEventArgs e) { dw.sFile = openFileDialog2.FileName; } private void saveFileDialog1_FileOk(object sender, CancelEventArgs e) { //} } } }
界面: