多线程拷贝文件根本就没多大意义....
磁盘的写入是同步了的和单线程效果一样.

解决方案 »

  1.   

    给你个例子,主要是那个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 stop = 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 (stop) 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();
                            stop = 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 (!stop) 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();
                stop = 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;
            }
     
        }
    }