Winfrom 线程实现 http、https 文件下载 显示下载进度详情

 

此实例主要是通过  System.Net.HttpWebRequest 和 System.Net.HttpWebResponse 来实现网络文件的下载

 并通过事件返回下载进度信息启用后台线程进行下载

 

项目结构:

 

 

项目中包含:

下载类:Downloader.cs  (用于启动线程下载文件,并返回相应的事件)

下载文件信息类:FileInfo.cs记录要下载的文件信息,包括:文件名称、文件下载路径、文件大小...)

信息显示界面: Form1.cs  控制开始下载、显示下载进度信息,界面如图2

 

1.下载类  Downloader.cs  详情

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;

namespace FileDownload
{
    /// <summary>
    /// 文件下载类
    /// </summary>
    public class Downloader
    {
        public delegate void DelProInfoArg(FileInfo _file);
        public delegate void DeldownloadEndArg();

        /// <summary>
        /// 开始下载文件,事件
        /// </summary>
        public event DelProInfoArg DownloadStartingEvent;
        /// <summary>
        /// 分包下载 事件(通知显示更新进度)
        /// </summary>
        public event DelProInfoArg DownloadedEvent;
        /// <summary>
        /// 一个文件下载结束,事件
        /// </summary>
        public event DelProInfoArg DownloadEndEvent;
        /// <summary>
        /// 所有的文件下载结束,事件
        /// </summary>
        public event DeldownloadEndArg DownloadALLEnd;

 


        private List<FileInfo> _waitDownloadFiles;

 

        /// <summary>
        /// 下载一批文件文件
        /// </summary>
        /// <param name="list">文件列表</param>
        public Downloader(List<FileInfo> list)
        {
            _waitDownloadFiles = list;
        }

 

        /// <summary>
        /// 开始下载
        /// </summary>
        public void Start()
        {
            System.Threading.Thread DownloadThread = new System.Threading.Thread(new System.Threading.ThreadStart(StartDownload));
            DownloadThread.IsBackground = true;
            DownloadThread.Start();
        }

 

        /// <summary>
        /// 线程启动,开始获取数据包
        /// </summary>
        private void StartDownload()
        {
            if (_waitDownloadFiles != null && _waitDownloadFiles.Count > 0)
            {

 

                int osize = 0;

 

                foreach (FileInfo file in _waitDownloadFiles)
                {
                    if (DownloadStartingEvent != null)//开始下载
                    {
                        DownloadStartingEvent(file);
                    }
                    try
                    {
                        #region 此处加上这一段是为了能够正常下载https URL的文件,如果不加上这段服务器验证的回调并返回true,则下载https文件时会发生错误,会提示服务器无法通过验证,无法正常下载

 

                        ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(ValidateServerCertificate);
                       
                        #endregion

 

                        System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(file.FileDownloadPath);
                        System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse();
                        file.SumSize = myrp.ContentLength;
          
                        System.IO.Stream st = myrp.GetResponseStream();
                        System.IO.Stream so = new System.IO.FileStream(file.FileSavePath, System.IO.FileMode.Create);
                       
                        byte[] by = new byte[1024];

 

                        osize = st.Read(by, 0, (int)by.Length);

 

                        while (osize > 0)
                        {
                            file.DownloadedSize = osize + file.DownloadedSize;

 

                            so.Write(by, 0, osize);
                        
                            osize = st.Read(by, 0, (int)by.Length);

 

                            if (DownloadedEvent != null)//获取一段数据包,更新显示
                            {
                                DownloadedEvent(file);
                            }
                        }
                        so.Close();
                        st.Close();

 

                        if (DownloadEndEvent != null)//一个文件下载完成
                        {
                            DownloadEndEvent(file);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }

 

                if (DownloadALLEnd != null)//下载结束
                {
                    DownloadALLEnd();
                }
            }
            else
            {
                if (DownloadALLEnd != null)//下载结束
                {
                    DownloadALLEnd();
                }
            }
        }

 

        /// <summary>
        /// 自定义的服务器证书验证回调方法,这里始终认为存在证书可以下载,返回True
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="certificate"></param>
        /// <param name="chain"></param>
        /// <param name="sslPolicyErrors"></param>
        /// <returns></returns>
        protected bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
    }
}

 

2.文件信息类  FileInfo.cs  详情

 

using System;
using System.Collections.Generic;
using System.Text;

 

namespace FileDownload
{
    /// <summary>
    /// 需要下载的文件信息
    /// </summary>
    public class FileInfo
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="_dowPath">下载路径</param>
        /// <param name="_savPath">文件保存路径</param>
        /// <param name="_fileName">文件名称</param>
        public FileInfo(string _dowPath, string _savPath, string _fileName)
        {
            fileDownloadPath = _dowPath;
            fileSavePath = _savPath;
            fileName = _fileName;
        }

 

        /// <summary>
        /// 文件下载路径,http路径
        /// </summary>
        private string fileDownloadPath;
        /// <summary>
        /// 文件下载路径,http路径
        /// </summary>
        public string FileDownloadPath
        {
            get { return fileDownloadPath; }
            set { fileDownloadPath = value; }
        }

 

        /// <summary>
        /// 文件存储路径,如D:\test\1.txt
        /// </summary>
        private string fileSavePath;
        /// <summary>
        /// 文件存储路径,如D:\test\1.txt
        /// </summary>
        public string FileSavePath
        {
            get { return fileSavePath; }
            set { fileSavePath = value; }
        }
        /// <summary>
        /// 文件名称
        /// </summary>
        private string fileName;
        /// <summary>
        /// 文件名称
        /// </summary>
        public string FileName
        {
            get { return fileName; }
            set { fileName = value; }
        }
        /// <summary>
        /// 文件总大小
        /// </summary>
        private long sumSize;
        /// <summary>
        /// 文件总大小
        /// </summary>
        public long SumSize
        {
            get { return sumSize; }
            set { sumSize = value; }
        }
        /// <summary>
        /// 已下载文件大小
        /// </summary>
        private long downloadedSize;
        /// <summary>
        /// 已下载文件大小
        /// </summary>
        public long DownloadedSize
        {
            get { return downloadedSize; }
            set { downloadedSize = value; }
        }
    }
}

            

3.文件信息类  Form1.cs  详情

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

 

namespace FileDownload
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

 

        List<FileInfo> listfiles = null;

 

        private void Form1_Load(object sender, EventArgs e)
        {
            LoadDownloadFileList();
        }

 

        /// <summary>
        /// 加载待下载的文件
        /// </summary>
        private void LoadDownloadFileList()
        {
            string Strpath = System.AppDomain.CurrentDomain.BaseDirectory;//获得应用程序的基目录,即bin/release或debug目录中
            listfiles = new List<FileInfo>();

 

            #region 填充数据
            FileInfo fileone = new FileInfo("http://down.360.cn/360sd/360sd_setup_se_3.0.0.2093G.exe", Path.Combine(Strpath, "文件1"), "文件1");
            listfiles.Add(fileone);

 

            FileInfo filetwo = new FileInfo("http://down.360.cn/360sd/360sd_setup_x64_2.0.0.2061.exe", Path.Combine(Strpath, "文件2"), "文件2");
            listfiles.Add(filetwo);
            #endregion

 

            ListViewItem item=null;
            foreach (FileInfo file in listfiles)
            {
                item=new ListViewItem (new string[]{file.FileName,file.FileDownloadPath,file.FileSavePath});
                listView1.Items.Add(item);
            }

 

        }

 

        /// <summary>
        /// 开始下载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStart_Click(object sender, EventArgs e)
        {
            Downloader download = new Downloader(listfiles);
            download.DownloadStartingEvent += new Downloader.DelProInfoArg(download_DownloadStartingEvent);//事件订阅,开始下载
            download.DownloadedEvent += new Downloader.DelProInfoArg(download_DownloadedEvent);//事件订阅,新获取了数据表,更新显示
            download.DownloadEndEvent += new Downloader.DelProInfoArg(download_DownloadEndEvent);//事件订阅,一个文件下载完成
            download.DownloadALLEnd += new Downloader.DeldownloadEndArg(download_DownloadALLEnd);//事件订阅,所有的下载任务结束
            download.Start();
        }

 

        #region 订阅事件,显示下载进度信息
        void download_DownloadALLEnd()
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new DelShowArg(ShowDownloadingInfo), new object[] {"下载已结束",0,0 });
            }
            else
            {
                ShowDownloadingInfo("下载已结束!", 0, 0);
            }
        }

 

        void download_DownloadEndEvent(FileInfo _file)
        {
            int Downloaded =(int)_file.DownloadedSize / 1024;
            int ALLdownload = (int)_file.SumSize / 1024;

 

            string strDownloadingInfo = string.Format("{0}  已下载完成!",_file.FileName);
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new DelShowArg(ShowDownloadingInfo), new object[] { strDownloadingInfo, ALLdownload, Downloaded });
            }
            else
            {
                ShowDownloadingInfo(strDownloadingInfo, ALLdownload, Downloaded);
            }
        }

 

        void download_DownloadedEvent(FileInfo _file)
        {
            int Downloaded = (int)_file.DownloadedSize / 1024;
            int ALLdownload = (int)_file.SumSize / 1024;

 

            string strDownloadingInfo = string.Format("{0}  正在下载中!", _file.FileName);
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new DelShowArg(ShowDownloadingInfo), new object[] { strDownloadingInfo, ALLdownload, Downloaded });
            }
            else
            {
                ShowDownloadingInfo(strDownloadingInfo, ALLdownload, Downloaded);
            }
        }

 

        void download_DownloadStartingEvent(FileInfo _file)
        {
            int Downloaded = (int)_file.DownloadedSize / 1024;
            int ALLdownload = (int)_file.SumSize / 1024;

 

            string strDownloadingInfo = string.Format("开始下载  {0}!", _file.FileName);
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new DelShowArg(ShowDownloadingInfo), new object[] { strDownloadingInfo, ALLdownload, Downloaded });
            }
            else
            {
                ShowDownloadingInfo(strDownloadingInfo, ALLdownload, Downloaded);
            }
        }

 

        /// <summary>
        /// 自定义数据显示委托
        /// </summary>
        /// <param name="_ShowInfo">显示的文字信息</param>
        /// <param name="_SumSize">总的数据包大小</param>
        /// <param name="_DownloadedSize">已下载数据包大小</param>
        private delegate void DelShowArg(string _ShowInfo, int _SumSize, int _DownloadedSize);

 

        /// <summary>
        /// 显示下载进度信息
        /// </summary>
        /// <param name="_ShowInfo">文字信息</param>
        /// <param name="_SumSize">总的数据包大小</param>
        /// <param name="_DownloadedSize">已下载大小</param>
        private void ShowDownloadingInfo(string _ShowInfo, int _SumSize, int _DownloadedSize)
        {
            lblProInfo.Text = _ShowInfo;

 

            if (_SumSize != 0 && _DownloadedSize != 0)
            {
                Probar.Maximum = _SumSize;
                Probar.Minimum = 0;
                Probar.Value = _DownloadedSize;

 

                lblPercent.Text = string.Format("{0}%", _DownloadedSize * 100 / _SumSize);
            }
        }

 

        #endregion
    }
}


  源码下载

 

 

 

转载于:https://www.cnblogs.com/luowanli/archive/2011/10/20/markeluo.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值