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