用c#实现多线程拷贝文件

wilconhao8 2009-06-20 12:35:58
这个具体怎么实现,有代码就更好了
...全文
362 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
ChrisAK 2009-06-20
  • 打赏
  • 举报
回复
多线程拷贝文件根本就没多大意义....
磁盘的写入是同步了的和单线程效果一样.
ToHai 2009-06-20
  • 打赏
  • 举报
回复
学习
wjq 2009-06-20
  • 打赏
  • 举报
回复
给你个例子,主要是那个oCopyFile函数。以及button3_click里的动作。关键就是文件拆分,以及多线程处理。
但却是没什么意义。小文件速度体现不出来,大文件要先分配磁盘空间才能开始复制,反而慢。
这是以前给别人做的毕业设计,写的比较乱,将就下吧

static float[] statusi;
static long[] postion;
static int cachNum = 1024 * 4096;
static string f1;
static bool chkway = true;
static string f2;
static int part = 5;
static bool stopmark = false;
static checkpoint cp;
static int picksize = 1024;
static float pctpause = -1;
static int arrypart = 1;
static writelogs log;
DateTime startime;
/// <summary>
/// 复制从传入的起始位置开始到该进程总共需要复制的长度的数据流
/// </summary>
/// <param name="ostar">所需的传输的参数,包括起始位置</param>
public static void oCopyFile(object ostar)
{
FileStream src = File.Open(f1, FileMode.Open, FileAccess.Read, FileShare.Read);
FileStream des = File.Open(f2, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write);
long sl = (long)(src.Length / part);
long size = sl + (src.Length % part == 0 ? 0 : 1);
object[] slst = ((System.Collections.ArrayList)ostar).ToArray();
int pos = (int)slst[0];
long star;
if ((long)slst[1] == (long)0)
{
star = pos * size;
}
else if ((long)slst[1] < 0)
{
star = src.Length / arrypart * (long)(-(long)slst[1] / (src.Length / arrypart));
size = size - (star - pos * size);
}
else
{
star = (long)slst[1];
size = size - (star - pos * size);
}
//开始复制文件
//每次读取一定大小的数据
for (long i = star; i < star + size; i = i + picksize)
{
postion[pos] = i;
if (stopmark) break;
byte[] b = new byte[(star + size - i) > picksize ? picksize : (star + size - i)];//(byte)src.ReadByte();
//stopT(pos);
src.Position = i;
src.Read(b, 0, b.Length);
des.Position = i;
if (src.Length < b.Length + i)
des.Write(b, 0, b.Length - 1);
else
des.Write(b, 0, b.Length);
//starTs();

//checkpoint方式时
if (!chkway)
{
if (postion[pos] / (long)(src.Length / arrypart) < picksize)
{
cp.UpdatePoint(f1, f2, postion);
}
}
//数组方式时
if ((i - star) % cachNum == 0)
{
des.Flush();
if (chkway)
{ cp.UpdatePoint(f1, f2, postion); }
}

if (pctpause > 0)
{
if (((int)(((float)(i - star)) / size * 10000)) >= (int)(pctpause * 100))
{
statusi[pos] = pctpause;
//更新checkpoint
if (chkway) cp.UpdatePoint(f1, f2, postion);
des.Flush();
src.Close();
des.Close();
stopmark = true;
return;
}

}
if(statusi.Length==1)
statusi[pos] = (int)(((float)(i)) / (sl) * 100);
else
statusi[pos] = (int)(((float)(i - star)) / (size) * 100);
}

des.Flush();
if (!stopmark) statusi[pos] = 101;
cp.UpdatePoint(f1, f2, postion);
src.Close();
des.Close();
}

private void button3_Click(object sender, EventArgs e)
{
if (textBox1.Text == "" || textBox2.Text == "")
{
MessageBox.Show("请选择要复制的文件以及目的地。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (File.Exists(textBox2.Text)) File.Delete(textBox2.Text);
if (checkBox1.Checked)
{
pctpause = (float)numericUpDown5.Value;
numericUpDown1.Value = 1;
}
else
{
pctpause = -1;
}
f1 = textBox1.Text;
f2 = textBox2.Text;
part = (int)numericUpDown1.Value;
cachNum = (int)(1024 * 1024 * numericUpDown2.Value);
statusi = new float[part];
postion = new long[part];
Thread[] t = new Thread[part];
listBox1.Items.Clear();
stopmark = false;
startime = DateTime.Now;
arrypart = (int)numericUpDown6.Value;
picksize = (int)numericUpDown4.Value * 1024;
for (int j = 0; j < t.Length; j++)
{
System.Collections.ArrayList al = new System.Collections.ArrayList();
al.Add(j);
al.Add((long)0);
t[j] = new Thread(Form1.oCopyFile);
t[j].Start(al);
listBox1.Items.Add("线程 " + (j + 1).ToString() + ": 正在启动");
}
log.AddLogs("开始复制", new float[] {0 }, f1,f2);
timer1.Enabled = true;
cp.AddPoint(f1, f2, postion);
numericUpDown1.Enabled = false;
numericUpDown4.Enabled = false;
button3.Enabled = false;
button4.Enabled = true;
dataGridView1.Enabled = false;
radioButton1.Enabled = false;
radioButton2.Enabled = false;
numericUpDown5.Enabled = false;
numericUpDown6.Enabled = false;
checkBox1.Enabled = false;
}

}
}
文件拷贝实例源码,学习关于IO文件流、多线程相关使用做参考。 private void button4_Click(object sender, EventArgs e) { this.progressBar1.Value = 0; this.label1.Text = "0%"; if (!File.Exists(this.textBox1.Text)) { MessageBox.Show("找不到目标文件!"); return; } if (!Directory.Exists(this.textBox2.Text)) { MessageBox.Show("请选择有效的保存路径!"); return; } string fileRead = this.textBox1.Text; string fileSave = Path.Combine(this.textBox2.Text, _fileName); System.Threading.ThreadPool.QueueUserWorkItem((o) => { using (IDisposable file = new FileStream(fileRead, FileMode.Open, FileAccess.Read), fileWrite = new FileStream(fileSave, FileMode.Create, FileAccess.Write)) { int count = 0; long fileLength =((FileStream)file).Length; //目标文件大小 //根据目标文件大小创建byte数组长度 byte[] data = new byte[fileLength > 1024 * 1024 * 30 ? 1024 * 1024 * 30 : fileLength]; //30M 1024 * 1024 * 30 int step = (int)Math.Ceiling(fileLength * 1.0 / data.Length); //分流段数 double n = (100 * 1.0 / step); //每次进度条累加 double m = 0; //累加统计 int spam = 1; //时间间隔 double speed = 0; //拷贝速度 do { DateTime time = DateTime.Now; //文件流操作 count = ((FileStream)file).Read(data, 0, data.Length); ((FileStream)fileWrite).Write(data, 0, count); //保存时间间隔,单位毫秒 spam = (DateTime.Now - time).Milliseconds > 0 ? (DateTime.Now - time).Milliseconds : spam;//必须大于0 //计算速度 单位k/s

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧