zoukankan      html  css  js  c++  java
  • 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
        }
    }


      源码下载

  • 相关阅读:
    poj 2411 Mondriaan's Dream 骨牌铺放 状压dp
    zoj 3471 Most Powerful (有向图)最大生成树 状压dp
    poj 2280 Islands and Bridges 哈密尔顿路 状压dp
    hdu 3001 Travelling 经过所有点(最多两次)的最短路径 三进制状压dp
    poj 3311 Hie with the Pie 经过所有点(可重)的最短路径 floyd + 状压dp
    poj 1185 炮兵阵地 状压dp
    poj 3254 Corn Fields 状压dp入门
    loj 6278 6279 数列分块入门 2 3
    VIM记事——大小写转换
    DKIM支持样本上传做检测的网站
  • 原文地址:https://www.cnblogs.com/luowanli/p/markeluo.html
Copyright © 2011-2022 走看看