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
        }
    }


      源码下载

  • 相关阅读:
    Google's Innovation Factory (and how testing adapts)
    虎年拜年帖
    [ZZ]让测试也敏捷起来
    Selenimu做爬虫续
    OKR的解说
    春秋航空的机上店铺
    免费TK域名试用
    快速排序_C语言实现
    第一篇博客
    C、C++代码格式优化软件献给编程爱好者
  • 原文地址:https://www.cnblogs.com/luowanli/p/markeluo.html
Copyright © 2011-2022 走看看