参考给出的方案

先求出文件和目录的数目:

1
2
3
4
5
6
7
8
9
10
static int Count(String src) {
int count = 1;
String[] sub = Directory.GetDirectories(src);
for (int i = 0; i < sub.Length; i++) {
count += Count(sub[i]);
}
String[] files = Directory.GetFiles(src);
count += files.Length;
return count;
}

设置ProgressBar属性Maximum为上面求出的数目,然后复制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
static void Copy(String src, String dest) {
try{
Directory.CreateDirectory(dest);
String[] sub = Directory.GetDirectories(src);
for (int i = 0; i < sub.Length; i++) {
String name = Path.GetFileName(sub[i]);
Copy(sub[i], dest + "\\" + name);
}
String[] files = Directory.GetFiles(src);
for (int i = 0; i < files.Length; i++) {
String name = Path.GetFileName(files[i]);
File.Copy(files[i], dest + "\\" + name);
}
progressBar1.Increment(files.Length + 1);//progressBar1是进度条。
}catch(Exception e){
Console.WriteLine(e);
}
}

拷贝文件夹:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
static public void CopyDirectory(string SourceDirectory, string TargetDirectory)
{
DirectoryInfo source = new DirectoryInfo(SourceDirectory);
DirectoryInfo target = new DirectoryInfo(TargetDirectory);

//Check If we have valid source
if(!source.Exists)
return;

if(!target.Exists)
target.Create();

//Copy Files
FileInfo[] sourceFiles = source.GetFiles();
for(int i = 0; i < sourceFiles.Length; ++i)
File.Copy(sourceFiles[i].FullName, target.FullName + "\\" + sourceFiles[i].Name,true);

//Copy directories
DirectoryInfo[] sourceDirectories = source.GetDirectories();
for(int j = 0; j < sourceDirectories.Length; ++j)
CopyDirectory(sourceDirectories[j].FullName,target.FullName +"\\" + sourceDirectories
}

自己最后实现的进度条显示方法的部分代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
//先求出文件和目录的数目:
static int Count(String src)
{
int count = 1;
String[] sub = Directory.GetDirectories(src);
for (int i = 0; i < sub.Length; i++)
{
count += Count(sub[i]);
}
String[] files = Directory.GetFiles(src);
count += files.Length;
return count;
}


/// <summary>
/// 复制文件及文件夹
/// </summary>
/// <param name="srcPath"></param>
/// <param name="destPath"></param>
private void copyDir(string srcPath, string destPath)
{
DirectoryInfo dir = new DirectoryInfo(srcPath);
//获取目录下的文件和子目录
FileSystemInfo[] fileinfo = dir.GetFileSystemInfos();
foreach (FileSystemInfo i in fileinfo)
{
if (i is DirectoryInfo)
{
//判断是否文件夹
if (!Directory.Exists(destPath + "\\" + i.Name))
{
//目标目录下不存在此文件夹即创建子文件夹
Directory.CreateDirectory(destPath + "\\" + i.Name);
}
//递归调用复制子文件夹
copyDir(i.FullName, destPath + "\\" + i.Name);
}
else
{
//不是文件夹即复制文件,true表示可以覆盖同名文件
//File.Copy(i.FullName, destPath + "\\" + i.Name, true);
CopyFile_1(i.FullName, destPath + "\\" + i.Name, 1024);//复制文件
}
FileCnt++;

//跨线程访问UI控件,更新主线程中dataGridView表格内容
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate
{
//此处可用于更新UI控件内容
this.progressBar2.Maximum = FileMax;
this.progressBar2.Value = FileCnt;
//this.progressBar2.Increment(FileCnt);//progressBar1是进度条。
this.label2.Text = (FileCnt*100 / FileMax).ToString() + "%";

this.richTextBox1.AppendText(FileCnt.ToString() + ":" + destPath + "\\" + i.Name + "\n");
this.richTextBox1.SelectionStart = this.richTextBox1.Text.Length; // 光标 移动到 最后一行
this.richTextBox1.ScrollToCaret();


//this.richTextBox1.AppendText(destPath + "\\" + i.Name+"\n");
}
));
}//跨线程访问UI控件,更新主线程中dataGridView表格内容
}
}



/// <summary>
/// 文件的复制
/// </summary>
/// <param FormerFile="string">源文件路径</param>
/// <param toFile="string">目的文件路径</param>
/// <param SectSize="int">传输大小</param>
/// <param progressBar="ProgressBar">ProgressBar控件</param>
public void CopyFile_1(string FormerFile, string toFile, int SectSize)
{
//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;//设置进度栏的最大值

if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate
{
//此处可用于更新UI控件内容
this.progressBar1.Value = 0;//增加进度栏的进度块
this.progressBar1.Minimum = 0;//设置进度栏的最小值为0
this.progressBar1.Maximum = max;//设置进度栏的最大值
}
));
}//跨线程访问UI控件,更新主线程中dataGridView表格内容


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;//增加进度栏的进度块

//跨线程访问UI控件,更新主线程中dataGridView表格内容
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate
{
//此处可用于更新UI控件内容
this.progressBar1.Value = this.progressBar1.Value + tem_n;//增加进度栏的进度块
//label1.Text = this.progressBar1.Value.ToString();
//label2.Text = FormerOpen.Length.ToString();
//label1.Text = ((this.progressBar1.Value / max) * 100).ToString() + "%";
//label2.Text = ((1-(FormerOpen.Length / FileMax)) * 100).ToString() + "%";
//label1.Text = (copied).ToString(); //当前复制大小
//label2.Text = (FormerOpen.Length).ToString(); //文件大小

label1.Text = (copied / (FormerOpen.Length / 100)).ToString() + "%";
}
));
}//跨线程访问UI控件,更新主线程中dataGridView表格内容


}
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 = "";
//}

//单文件拷贝j结束
//跨线程访问UI控件,更新主线程中dataGridView表格内容
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate
{
//此处可用于更新UI控件内容
this.progressBar1.Value = max;//增加进度栏的进度块
label1.Text = "100%";
}
));
}//跨线程访问UI控件,更新主线程中dataGridView表格内容

}


private void button5_Click(object sender, EventArgs e)
{
//Console.WriteLine("文件数:" + Count(textBox1.Text));

string path = textBox1.Text;
string dest = textBox2.Text;

timer1.Start(); //开始记录复制时间
//dt1
dt1 = DateTime.Parse("00:00:00");
Lab_Time.Text = "0:00:00";


//progressBar2.Maximum = Count(path);//设置进度栏的最大值
//创建线程
Thread copyFilesThread = new Thread(() =>
{
//sw.Start();
//CopyFiles(path, dest);
FileCnt = 1;
//FileMax = Count(path);
//copyDir(path, dest);
//Console.WriteLine("FileCnt:" + FileCnt);
//Console.WriteLine("FileMax:" + FileMax);

//判断选择的路径是文件还是文件夹
if (File.Exists(path))
{
string name = System.IO.Path.GetFileName(path);//名称
Console.WriteLine("是文件{0}", path);
CopyFile_1(path, dest+"\\"+ name, 1024);
//timer1.Stop(); //开始记录复制时间
//Copy(path, dest);
}
else if (Directory.Exists(path))
{
Console.WriteLine("是文件夹");
FileMax = Count(path);
copyDir(path, dest);
}
else
{
Console.WriteLine("都不是");
}

timer1.Stop(); //开始记录复制时间
MessageBox.Show("复制完成!");
//Console.WriteLine("复制时间为:" + sw.Elapsed);
//sw.Stop();

});
copyFilesThread.Start(); //启动线程

}


相关链接(侵删)

  1. 如何用C#实现文件及文件夹复制,且显示复制的进度条

=================我是分割线=================

欢迎到公众号来唠嗑: