首页 新闻 会员 周边

多文件下载

1
悬赏园豆:100 [已关闭问题] 关闭于 2011-02-11 02:29

我目前已经完成单个文件的多线程下载,我贴代码出来,求高手赐教我要怎么弄多个文件下载,我这个只能下载单文件:

  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;//网络功能
using System.IO;//流支持
using System.Threading;//线程支持
using System.Windows.Forms;
namespace ToolFrom.Common
{
    public class HttpFile
    {
        public int threadcount;//下载文件线程的数量
        public string fileUrl;//下载文件的远程地址URL
        public string filename;//保存到本地的文件名称
        public string documentname;

 

        private static AutoResetEvent[] EventS;//创建AutoResetEvent对象(多线程调度指令)
        private Thread DownFileMain;//下载文件主线程
        private Thread[] DownFiles;//下载文件数据块线程
        public HttpFile(string url, string name, int count)
        {
            documentname = name.Substring(name.LastIndexOf('\\')+1);
            MsgClass.docname = documentname;
            fileUrl = url;
            filename = name + ".lu";//没有下载完成前文件的后缀名为“.lu”
            threadcount = count;
            DownFiles = new Thread[threadcount];
            MsgClass.ThreadCount = threadcount;//信息数据类线程个数
            EventS = new AutoResetEvent[threadcount];
            for (int i = 0; i < threadcount; i++)
                EventS[i] = new AutoResetEvent(false);
        }
        public void Abort()//取消文件下载
        {
            for (int i = 0; i < threadcount; i++)
            {
                if (DownFiles[i].IsAlive) DownFiles[i].Abort();
            }
            if (DownFileMain.IsAlive) DownFileMain.Abort();
            MsgClass.Msg = "下载文件取消";
        }
        public void downfile()//多线程下载文件
        {
            ServicePointManager.DefaultConnectionLimit = 25;//默认情况下,System.Net 对每个主机的每个应用程序使用两个连接。至少要大于线程数。但:初始化后改变此属性没有影响
            //ServicePointManager.DefaultConnectionLimit = threadcount;这里必须大于线程数
            DownFileMain = new Thread(new ThreadStart(getdownfile));//获取文件大小、多线程下载多文件段
            DownFileMain.Start();
        }
        private void getdownfile()//获取文件大小、多线程下载多文件段
        {
            try
            {
                MsgClass.Msg = "正在尝试获取资源";//信息
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(fileUrl);//需要下载的文件全路径
                int filesize = (int)request.GetResponse().ContentLength;//取得下载文件的大小
                MsgClass.FileSize = filesize;
                request.Abort();
                int fileonethreadsize = filesize / threadcount;//平均分配
                FileStream WriteFS = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);//生成保存的文件
                WriteFS.Write(new byte[filesize], 0, filesize);//用空内容填充
                WriteFS.Close();
             //   MsgClass.Msg = threadcount.ToString() + " 个线程正在下载文件。";//信息
                MsgClass.Msg = "资源正在下载中";
                MsgClass.StartTime = DateTime.Now;
                for (int i = 0; i < threadcount; i++)
                {
                    threadreceive tr;
                    if (i == threadcount - 1)//最后一个下载线程
                        tr = new threadreceive(i, fileonethreadsize * i, filesize, fileUrl, filename);
                    else
                        tr = new threadreceive(i, fileonethreadsize * i, fileonethreadsize * i + fileonethreadsize - 1, fileUrl, filename);
                    DownFiles[i] = new Thread(new ThreadStart(tr.receive));//启动接收数据块线程组(threadcount个)
                    DownFiles[i].Start();
                }
                WaitHandle.WaitAll(EventS);//等待所有线程都结束的信号
                int temp = 0;
                for (int i = 0; i < MsgClass.ThreadCount; i++)
                    temp += MsgClass.threadsistrue[i];
                if (temp == MsgClass.ThreadCount)//所有线程下载成功
                {
                    if (File.Exists(filename.Substring(0, filename.Length - 3))) File.Delete(filename.Substring(0, filename.Length - 3));//下载的文件已经存在,则先删除
                    File.Move(filename, filename.Substring(0, filename.Length - 3));//文件下载完成后更名,去掉后缀名“.lu”。
                    MsgClass.Msg = "下载文件完成";//信息
                }
                else
                    MsgClass.Msg = "下载文件失败";//信息
            }
            catch (ThreadAbortException)
            {
                MsgClass.Msg = "下载文件取消";//信息
                MsgClass.ThreadCount = 0;
                MsgClass.FileSize = 0;
            }
            catch
            {
                MsgClass.Msg = "网络故障下载失败";//信息
            }
        }
        private class threadreceive//线程下载文件类
        {
            private int threadIndex;//线程号
            private int from, to;//文件下载的开始和结束位置
            private string fileUrl;//下载文件的远程地址URL
            private string filename;//保存到本地的文件名称
            public threadreceive(int index, int f, int t, string Url, string Name)
            {
                threadIndex = index;
                from = f;
                to = t;
                fileUrl = Url;
                filename = Name;
            }
            public void receive()//接收线程
            {
                FileStream WriteFS = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);//打开保存的文件
                WriteFS.Seek(from, SeekOrigin.Begin);//文件定位于当前线程写内容的位置
                byte[] nbytes = new byte[1024 * 10];
                try
                {
                    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(fileUrl);//有时网络不正常会连接不上,这里可以作多次连接
                    request.AddRange(from, to);//接收的起始位置及接收的结束位置
                    Stream ns = request.GetResponse().GetResponseStream();//获得接收流
                    int nreadsize;
                    while ((nreadsize = ns.Read(nbytes, 0, nbytes.Length)) > 0)
                    {
                        WriteFS.Write(nbytes, 0, nreadsize);
                        MsgClass.threadsdata[threadIndex] += nreadsize;//单个线程总共下载数据量
                    }
                    ns.Close();
                    MsgClass.threadsistrue[threadIndex] = 1;//此线程下载数据块成功
                }
                catch { }
                WriteFS.Close();
                HttpFile.EventS[threadIndex].Set();//发送本线程已经结束的信号
            }
        }
    }
    /// <summary>
    /// 多线程下载文件,线程之间信息数据共享类
    /// </summary>
    public class MsgClass
    {
        private static int threadcount;//线程数量

        public static int[] threadsdata;//线程下载文件完成量
        public static int[] threadsistrue;//线程下载文件是否完全成功
        public static string Msg = "下载文件开始";
        public static int FileSize;//下载文件大小
        public static DateTime StartTime;//开始下载时间
        public static string docname;
        public static int ThreadCount
        {
            get
            {
                return threadcount;
            }
            set
            {
                threadcount = value;
                threadsdata = new int[threadcount];
                for (int i = 0; i < threadcount; i++)
                    threadsdata[i] = 0;
                threadsistrue = new int[threadcount];
                for (int i = 0; i < threadcount; i++)
                    threadsistrue[i] = 0;
            }
        }
    }
}

 

 

    求教 多文件下载怎么做? 如果您对多文件下载不明了,如果您知道断点续传也可以教我一下,保证另外追加分,真心求教!  我的邮箱 demon28@163.com 我的QQ:274733956

问题补充: HttpFile hf = new HttpFile(Downwindow.URL.ToString(), Downwindow.saveurl.Text + "\\" + Downwindow.FileName.ToString(), 5); hf.downfile(); 调用该方法便可多线程下载
Near_wen的主页 Near_wen | 初学一级 | 园豆:11
提问于:2011-01-18 18:12
< >
分享
所有回答(1)
0

Thread[] threads = new Thread[100];
for(int x = 0; x < 100; x++){
threads[x]
= new Thread(getdownfile);
threads[x].Start();
}

当然,你的getdownfile可能还需要做些修改,没细看.

I,Robot | 园豆:9783 (大侠五级) | 2011-01-19 12:26
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册