winform 拷贝文件时用进度条显示拷贝进度
窗体上控件有:一个文本框:txtCopyFile(用于显示需拷贝文件的路径),两个button:btnOpenFile(用于选择需打开的文件),btnCopyFile(拷贝文件);一个progressBar:progressBar1(用于显示进度条)
字段和属性:
Code
1 Stream stream = null; //异步流对象
2 Byte[] bytes = null; //包含4K文件的字节数组
3 const Int32 BUFFER_SIZE = 4096; //每次拷贝4K的文件, 只考虑大于4K的文件
4 Int64 totalSize = 0; //文件的总大小
5 Int64 position = 0; //拷贝文件的当前位置
6 String savePath = String.Empty; //保存文件的路径
7 String openPath = String.Empty; //打开文件的路径
8 FileStream fsRead = null; //读文件的流
1 Stream stream = null; //异步流对象
2 Byte[] bytes = null; //包含4K文件的字节数组
3 const Int32 BUFFER_SIZE = 4096; //每次拷贝4K的文件, 只考虑大于4K的文件
4 Int64 totalSize = 0; //文件的总大小
5 Int64 position = 0; //拷贝文件的当前位置
6 String savePath = String.Empty; //保存文件的路径
7 String openPath = String.Empty; //打开文件的路径
8 FileStream fsRead = null; //读文件的流
拷贝事件:
Code
1 /**//// <summary>
2 /// 拷贝
3 /// </summary>
4 private void btnCopyFile_Click(object sender, EventArgs e)
5 {
6 try
7 {
8 position = 0;
9
10 SaveFileDialog save = new SaveFileDialog();
11 if (save.ShowDialog() == DialogResult.OK)
12 {
13 savePath = save.FileName;
14
15 if (File.Exists(save.FileName))
16 {
17 File.Delete(save.FileName);
18 }
19 }
20
21 //返回需拷贝文件的流
22 fsRead = new FileStream(this.txtCopyFile.Text.Trim(), FileMode.Open, FileAccess.Read);
23 totalSize = fsRead.Length;
24
25 stream = fsRead;
26
27 if (totalSize > BUFFER_SIZE)
28 {
29 bytes = new Byte[BUFFER_SIZE];
30
31 //调用异步读方法将流中的数据写到bytes数组中
32 stream.BeginRead(bytes, 0, bytes.Length, new AsyncCallback(AsyncCopyFile), null);
33 }
34 else
35 {
36
37 bytes = new Byte[totalSize];
38 stream.Read(bytes, 0, bytes.Length);
39
40 //将读取的数据添加到新的文件
41 FileStream fsWrite = new FileStream(savePath + "." + Path.GetExtension(openPath), FileMode.Append, FileAccess.Write);
42 fsWrite.Write(bytes, 0, bytes.Length);
43 fsWrite.Flush();
44 fsWrite.Close();//关闭输出流
45
46 position = totalSize;
47 ShowProgressSchedule();//显示进度
48
49 fsRead.Close(); //关闭输入流
50 stream.Close();
51 MessageBox.Show("文件拷贝完成!");
52
53 }
54 }
55 catch (Exception ex)
56 {
57 }
58
59 }
60
61
62 /**//// <summary>
63 /// 读取字节数组完成方法
64 /// </summary>
65 private void AsyncCopyFile(IAsyncResult isr)
66 {
67 Int32 readLength = 0;
68
69 try
70 {
71 lock (stream)
72 {
73 readLength = stream.EndRead(isr);//读取完成后游标的位置
74 }
75
76 position += readLength; //读取数据的当前位置
77
78 //将读取的数据添加到新的文件
79 FileStream fsWrite = new FileStream(savePath + "." + Path.GetExtension(openPath), FileMode.Append, FileAccess.Write);
80 fsWrite.Write(bytes, 0, bytes.Length);
81 fsWrite.Flush();
82 fsWrite.Close();
83
84
85 //在界面上显示progress的进度
86 ShowProgressSchedule();
87
88
89 //数据拷贝完成
90 if (position >= totalSize)
91 {
92 fsRead.Close();
93 stream.Close();
94 MessageBox.Show("文件拷贝完成!");
95 return;
96 }
97
98
99 lock (stream)
100 {
101 Int64 leftSize = totalSize - position;//获得未读数据的字节大小
102
103 if (leftSize < BUFFER_SIZE)
104 {
105 bytes = new Byte[leftSize];
106 }
107
108 //调用异步读取函数
109 stream.BeginRead(bytes, 0, bytes.Length, new AsyncCallback(AsyncCopyFile), null);
110 }
111 }
112 catch (Exception ex)
113 {
114 }
115 }
116
117
118
119 delegate void ShowProgressScheduleDele();
120 private void ShowProgressSchedule()
121 {
122 // 判断是否在线程中访问 chinese
123 if (!this.progressBar1.InvokeRequired)
124 {
125 // 不是的话直接操作控件
126 this.progressBar1.Maximum = (Int32)totalSize;
127 this.progressBar1.Value = (Int32)position;
128 }
129 else
130 {
131 // 是的话启用delegate访问
132 ShowProgressScheduleDele showProgress = new ShowProgressScheduleDele(ShowProgressSchedule);
133 // 如使用Invoke会等到函数调用结束,而BeginInvoke不会等待直接往后走
134 this.BeginInvoke(showProgress, new object[] { });
135 }
136 }
1 /**//// <summary>
2 /// 拷贝
3 /// </summary>
4 private void btnCopyFile_Click(object sender, EventArgs e)
5 {
6 try
7 {
8 position = 0;
9
10 SaveFileDialog save = new SaveFileDialog();
11 if (save.ShowDialog() == DialogResult.OK)
12 {
13 savePath = save.FileName;
14
15 if (File.Exists(save.FileName))
16 {
17 File.Delete(save.FileName);
18 }
19 }
20
21 //返回需拷贝文件的流
22 fsRead = new FileStream(this.txtCopyFile.Text.Trim(), FileMode.Open, FileAccess.Read);
23 totalSize = fsRead.Length;
24
25 stream = fsRead;
26
27 if (totalSize > BUFFER_SIZE)
28 {
29 bytes = new Byte[BUFFER_SIZE];
30
31 //调用异步读方法将流中的数据写到bytes数组中
32 stream.BeginRead(bytes, 0, bytes.Length, new AsyncCallback(AsyncCopyFile), null);
33 }
34 else
35 {
36
37 bytes = new Byte[totalSize];
38 stream.Read(bytes, 0, bytes.Length);
39
40 //将读取的数据添加到新的文件
41 FileStream fsWrite = new FileStream(savePath + "." + Path.GetExtension(openPath), FileMode.Append, FileAccess.Write);
42 fsWrite.Write(bytes, 0, bytes.Length);
43 fsWrite.Flush();
44 fsWrite.Close();//关闭输出流
45
46 position = totalSize;
47 ShowProgressSchedule();//显示进度
48
49 fsRead.Close(); //关闭输入流
50 stream.Close();
51 MessageBox.Show("文件拷贝完成!");
52
53 }
54 }
55 catch (Exception ex)
56 {
57 }
58
59 }
60
61
62 /**//// <summary>
63 /// 读取字节数组完成方法
64 /// </summary>
65 private void AsyncCopyFile(IAsyncResult isr)
66 {
67 Int32 readLength = 0;
68
69 try
70 {
71 lock (stream)
72 {
73 readLength = stream.EndRead(isr);//读取完成后游标的位置
74 }
75
76 position += readLength; //读取数据的当前位置
77
78 //将读取的数据添加到新的文件
79 FileStream fsWrite = new FileStream(savePath + "." + Path.GetExtension(openPath), FileMode.Append, FileAccess.Write);
80 fsWrite.Write(bytes, 0, bytes.Length);
81 fsWrite.Flush();
82 fsWrite.Close();
83
84
85 //在界面上显示progress的进度
86 ShowProgressSchedule();
87
88
89 //数据拷贝完成
90 if (position >= totalSize)
91 {
92 fsRead.Close();
93 stream.Close();
94 MessageBox.Show("文件拷贝完成!");
95 return;
96 }
97
98
99 lock (stream)
100 {
101 Int64 leftSize = totalSize - position;//获得未读数据的字节大小
102
103 if (leftSize < BUFFER_SIZE)
104 {
105 bytes = new Byte[leftSize];
106 }
107
108 //调用异步读取函数
109 stream.BeginRead(bytes, 0, bytes.Length, new AsyncCallback(AsyncCopyFile), null);
110 }
111 }
112 catch (Exception ex)
113 {
114 }
115 }
116
117
118
119 delegate void ShowProgressScheduleDele();
120 private void ShowProgressSchedule()
121 {
122 // 判断是否在线程中访问 chinese
123 if (!this.progressBar1.InvokeRequired)
124 {
125 // 不是的话直接操作控件
126 this.progressBar1.Maximum = (Int32)totalSize;
127 this.progressBar1.Value = (Int32)position;
128 }
129 else
130 {
131 // 是的话启用delegate访问
132 ShowProgressScheduleDele showProgress = new ShowProgressScheduleDele(ShowProgressSchedule);
133 // 如使用Invoke会等到函数调用结束,而BeginInvoke不会等待直接往后走
134 this.BeginInvoke(showProgress, new object[] { });
135 }
136 }
想进一步讨论或下载源代码,请加入QQ群:74085440