




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C#实现支持断点续传多线程下载客户端工具类C#实现支持断点续传多线程下载的 Http Web 客户端工具类 (C# DIY HttpWebClient),感兴趣的朋友可以参考下本文,或许对你有所帮助代码如下:/* .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (C# DIY HttpWebClient) * Reflector 了一下 System.Net.WebClient ,改写或增加了若干: * DownLoad、Upload 相关方法! * DownLoad 相关改动较大! * 增加了 DataReceive、ExceptionOccurrs 事件!
2、* 了解服务器端与客户端交互的 HTTP 协议参阅: * 使文件下载的自定义连接支持 FlashGet 的断点续传多线程链接下载! JSP/Servlet 实现! * * 使文件下载的自定义连接支持 FlashGet 的断点续传多线程链接下载! C#/ASP.Net 实现! * */ /2005-03-14 修订: /* .Net/C#: 实现支持断点续传多线程下载的工具类 * Reflector 了一下 System.Net.WebClient ,改写或增加了若干: * DownLoad、Upload 相关方法! * 增加了 DataReceive、ExceptionOccurrs事件 */
3、 namespace Microshaoft.Utils using System; using System.IO; using System.Net; using System.Text; using System.Security; using System.Threading; using System.Collections.Specialized; / <summary> / 记录下载的字节位置 / </summary> public class DownLoadState private string _FileName; private string _
4、AttachmentName; private int _Position; private string _RequestURL; private string _ResponseURL; private int _Length; private byte _Data; public string FileName get return _FileName; public int Position get return _Position; public int Length get return _Length; public string AttachmentName get retur
5、n _AttachmentName; public string RequestURL get return _RequestURL; public string ResponseURL get return _ResponseURL; public byte Data get return _Data; internal DownLoadState(string RequestURL, string ResponseURL, string FileName, string AttachmentName, int Position, int Length, byte Data) this._F
6、ileName = FileName; this._RequestURL = RequestURL; this._ResponseURL = ResponseURL; this._AttachmentName = AttachmentName; this._Position = Position; this._Data = Data; this._Length = Length; internal DownLoadState(string RequestURL, string ResponseURL, string FileName, string AttachmentName, int Po
7、sition, int Length, ThreadCallbackHandler tch) this._RequestURL = RequestURL; this._ResponseURL = ResponseURL; this._FileName = FileName; this._AttachmentName = AttachmentName; this._Position = Position; this._Length = Length; this._ThreadCallback = tch; internal DownLoadState(string RequestURL, str
8、ing ResponseURL, string FileName, string AttachmentName, int Position, int Length) this._RequestURL = RequestURL; this._ResponseURL = ResponseURL; this._FileName = FileName; this._AttachmentName = AttachmentName; this._Position = Position; this._Length = Length; private ThreadCallbackHandler _Thread
9、Callback; public HttpWebClient httpWebClient get return this._hwc; set this._hwc = value; internal Thread thread get return _thread; set _thread = value; private HttpWebClient _hwc; private Thread _thread; / internal void StartDownloadFileChunk() if (this._ThreadCallback != null) this._ThreadCallbac
10、k(this._RequestURL, this._FileName, this._Position, this._Length); this._hwc.OnThreadProcess(this._thread); /委托代理线程的所执行的方法签名一致 public delegate void ThreadCallbackHandler(string S, string s, int I, int i); /异常处理动作 public enum ExceptionActions Throw, CancelAll, Ignore, Retry / <summary> / 包含 Exc
11、eption 事件数据的类 / </summary> public class ExceptionEventArgs : System.EventArgs private System.Exception _Exception; private ExceptionActions _ExceptionAction; private DownLoadState _DownloadState; public DownLoadState DownloadState get return _DownloadState; public Exception Exception get retur
12、n _Exception; public ExceptionActions ExceptionAction get return _ExceptionAction; set _ExceptionAction = value; internal ExceptionEventArgs(System.Exception e, DownLoadState DownloadState) this._Exception = e; this._DownloadState = DownloadState; / <summary> / 包含 DownLoad 事件数据的类 / </summar
13、y> public class DownLoadEventArgs : System.EventArgs private DownLoadState _DownloadState; public DownLoadState DownloadState get return _DownloadState; public DownLoadEventArgs(DownLoadState DownloadState) this._DownloadState = DownloadState; public class ThreadProcessEventArgs : System.EventArg
14、s private Thread _thread; public Thread thread get return this._thread; public ThreadProcessEventArgs(Thread thread) this._thread = thread; / <summary> / 支持断点续传多线程下载的类 / </summary> public class HttpWebClient private static object _SyncLockObject = new object(); public delegate void DataR
15、eceiveEventHandler(HttpWebClient Sender, DownLoadEventArgs e); public event DataReceiveEventHandler DataReceive; /接收字节数据事件 public delegate void ExceptionEventHandler(HttpWebClient Sender, ExceptionEventArgs e); public event ExceptionEventHandler ExceptionOccurrs; /发生异常事件 public delegate void ThreadP
16、rocessEventHandler(HttpWebClient Sender, ThreadProcessEventArgs e); public event ThreadProcessEventHandler ThreadProcessEnd; /发生多线程处理完毕事件 private int _FileLength; /下载文件的总大小 public int FileLength get return _FileLength; / <summary> / 分块下载文件 / </summary> / <param name="Address"
17、;>URL 地址</param> / <param name="FileName">保存到本地的路径文件名</param> / <param name="ChunksCount">块数,线程数</param> public void DownloadFile(string Address, string FileName, int ChunksCount) int p = 0; / position int s = 0; / chunk size string a = null; Http
18、WebRequest hwrq; HttpWebResponse hwrp = null; try hwrq = (HttpWebRequest) WebRequest.Create(this.GetUri(Address); hwrp = (HttpWebResponse) hwrq.GetResponse(); long L = hwrp.ContentLength; hwrq.Credentials = this.m_credentials; L = (L = -1) | (L > 0x7fffffff) ? (long) 0x7fffffff) : L; /Int32.MaxVa
19、lue 该常数的值为 2,147,483,647; 即十六进制的 0x7FFFFFFF int l = (int) L; this._FileLength = l; / 在本地预定空间(竟然在多线程下不用先预定空间) / FileStream sw = new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); / sw.Write(new bytel, 0, l); / sw.Close(); / sw = null; bool b = (hwrp.Headers&qu
20、ot;Accept-Ranges" != null & hwrp.Headers"Accept-Ranges" = "bytes"); a = hwrp.Headers"Content-Disposition" /attachment if (a != null) a = a.Substring(a.LastIndexOf("filename=") + 9); else a = FileName; int ss = s; if (b) s = l / ChunksCount; if (s <
21、 2 * 64 * 1024) /块大小至少为 128 K 字节 s = 2 * 64 * 1024; ss = s; int i = 0; while (l > s) l -= s; if (l < s) s += l; if (i+ > 0) DownLoadState x = new DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a, p, s, new ThreadCallbackHandler(this.DownloadFileChunk); / 单线程下载 / x.StartDown
22、loadFileChunk(); x.httpWebClient = this; /多线程下载 Thread t = new Thread(new ThreadStart(x.StartDownloadFileChunk); /this.OnThreadProcess(t); t.Start(); p += s; s = ss; byte buffer = this.ResponseAsBytes(Address, hwrp, s, FileName); this.OnThreadProcess(Thread.CurrentThread); / lock (_SyncLockObject) /
23、 / this._Bytes += buffer.Length; / catch (Exception e) ExceptionActions ea = ExceptionActions.Throw; if (this.ExceptionOccurrs != null) DownLoadState x = new DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a, p, s); ExceptionEventArgs eea = new ExceptionEventArgs(e, x); ExceptionOccu
24、rrs(this, eea); ea = eea.ExceptionAction; if (ea = ExceptionActions.Throw) if (!(e is WebException) && !(e is SecurityException) throw new WebException("net_webclient", e); throw; internal void OnThreadProcess(Thread t) if (ThreadProcessEnd != null) ThreadProcessEventArgs tpea = ne
25、w ThreadProcessEventArgs(t); ThreadProcessEnd(this, tpea); / <summary> / 下载一个文件块,利用该方法可自行实现多线程断点续传 / </summary> / <param name="Address">URL 地址</param> / <param name="FileName">保存到本地的路径文件名</param> / <param name="Length">块大小</p
26、aram> public void DownloadFileChunk(string Address, string FileName, int FromPosition, int Length) HttpWebResponse hwrp = null; string a = null; try /this._FileName = FileName; HttpWebRequest hwrq = (HttpWebRequest) WebRequest.Create(this.GetUri(Address); /hwrq.Credentials = this.m_credentials; h
27、wrq.AddRange(FPosition); hwrp = (HttpWebResponse) hwrq.GetResponse(); a = hwrp.Headers"Content-Disposition" /attachment if (a != null) a = a.Substring(a.LastIndexOf("filename=") + 9); else a = FileName; byte buffer = this.ResponseAsBytes(Address, hwrp, Length, FileName); / lock (
28、_SyncLockObject) / / this._Bytes += buffer.Length; / catch (Exception e) ExceptionActions ea = ExceptionActions.Throw; if (this.ExceptionOccurrs != null) DownLoadState x = new DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a, FromPosition, Length); ExceptionEventArgs eea = new Excep
29、tionEventArgs(e, x); ExceptionOccurrs(this, eea); ea = eea.ExceptionAction; if (ea = ExceptionActions.Throw) if (!(e is WebException) && !(e is SecurityException) throw new WebException("net_webclient", e); throw; internal byte ResponseAsBytes(string RequestURL, WebResponse Respons
30、e, long Length, string FileName) string a = null; /AttachmentName int P = 0; /整个文件的位置指针 int num2 = 0; try a = Response.Headers"Content-Disposition" /attachment if (a != null) a = a.Substring(a.LastIndexOf("filename=") + 9); long num1 = Length; /Response.ContentLength; bool flag1
31、= false; if (num1 = -1) flag1 = true; num1 = 0x10000; /64k byte buffer1 = new byte(int) num1; int p = 0; /本块的位置指针 string s = Response.Headers"Content-Range" if (s != null) s = s.Replace("bytes ", ""); s = s.Substring(0, s.IndexOf("-"); P = Convert.ToInt32(s);
32、int num3 = 0; Stream S = Response.GetResponseStream(); do num2 = S.Read(buffer1, num3, (int) num1) - num3); num3 += num2; if (flag1 && (num3 = num1) num1 += 0x10000; byte buffer2 = new byte(int) num1; Buffer.BlockCopy(buffer1, 0, buffer2, 0, num3); buffer1 = buffer2; / lock (_SyncLockObject)
33、 / / this._bytes += num2; / if (num2 > 0) if (this.DataReceive != null) byte buffer = new bytenum2; Buffer.BlockCopy(buffer1, p, buffer, 0, buffer.Length); DownLoadState dls = new DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, num2, buffer); DownLoadEventArgs dlea =
34、new DownLoadEventArgs(dls); /触发事件 this.OnDataReceive(dlea); /System.Threading.Thread.Sleep(100); p += num2; /本块的位置指针 P += num2; /整个文件的位置指针 else break; while (num2 != 0); S.Close(); S = null; if (flag1) byte buffer3 = new bytenum3; Buffer.BlockCopy(buffer1, 0, buffer3, 0, num3); buffer1 = buffer3; re
35、turn buffer1; catch (Exception e) ExceptionActions ea = ExceptionActions.Throw; if (this.ExceptionOccurrs != null) DownLoadState x = new DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, num2); ExceptionEventArgs eea = new ExceptionEventArgs(e, x); ExceptionOccurrs(this, e
36、ea); ea = eea.ExceptionAction; if (ea = ExceptionActions.Throw) if (!(e is WebException) && !(e is SecurityException) throw new WebException("net_webclient", e); throw; return null; private void OnDataReceive(DownLoadEventArgs e) /触发数据到达事件 DataReceive(this, e); public byte UploadFi
37、le(string address, string fileName) return this.UploadFile(address, "POST", fileName, "file"); public string UploadFileEx(string address, string method, string fileName, string fieldName) return Encoding.ASCII.GetString(UploadFile(address, method, fileName, fieldName); public byt
38、e UploadFile(string address, string method, string fileName, string fieldName) byte buffer4; FileStream stream1 = null; try fileName = Path.GetFullPath(fileName); string text1 = "-" + DateTime.Now.Ticks.ToString("x"); string text2 = "application/octet-stream" stream1 =
39、new FileStream(fileName, FileMode.Open, FileAccess.Read); WebRequest request1 = WebRequest.Create(this.GetUri(address); request1.Credentials = this.m_credentials; request1.ContentType = "multipart/form-data; boundary=" + text1; request1.Method = method; string textArray1 = new string7 &quo
40、t;-", text1, "rnContent-Disposition: form-data; name="" + fieldName + "" filename="", Path.GetFileName(fileName), ""rnContent-Type: ", text2, "rnrn" string text3 = string.Concat(textArray1); byte buffer1 = Encoding.UTF8.GetBytes(text3)
41、; byte buffer2 = Encoding.ASCII.GetBytes("rn-" + text1 + "rn"); long num1 = 0x7fffffffffffffff; try num1 = stream1.Length; request1.ContentLength = (num1 + buffer1.Length) + buffer2.Length; catch byte buffer3 = new byteMath.Min(0x2000, (int) num1); using (Stream stream2 = request
42、1.GetRequestStream() int num2; stream2.Write(buffer1, 0, buffer1.Length); do num2 = stream1.Read(buffer3, 0, buffer3.Length); if (num2 != 0) stream2.Write(buffer3, 0, num2); while (num2 != 0); stream2.Write(buffer2, 0, buffer2.Length); stream1.Close(); stream1 = null; WebResponse response1 = request
43、1.GetResponse(); buffer4 = this.ResponseAsBytes(response1); catch (Exception exception1) if (stream1 != null) stream1.Close(); stream1 = null; if (!(exception1 is WebException) && !(exception1 is SecurityException) /throw new WebException(SR.GetString("net_webclient"), exception1);
44、 throw new WebException("net_webclient", exception1); throw; return buffer4; private byte ResponseAsBytes(WebResponse response) int num2; long num1 = response.ContentLength; bool flag1 = false; if (num1 = -1) flag1 = true; num1 = 0x10000; byte buffer1 = new byte(int) num1; Stream stream1 =
45、 response.GetResponseStream(); int num3 = 0; do num2 = stream1.Read(buffer1, num3, (int) num1) - num3); num3 += num2; if (flag1 && (num3 = num1) num1 += 0x10000; byte buffer2 = new byte(int) num1; Buffer.BlockCopy(buffer1, 0, buffer2, 0, num3); buffer1 = buffer2; while (num2 != 0); stream1.C
46、lose(); if (flag1) byte buffer3 = new bytenum3; Buffer.BlockCopy(buffer1, 0, buffer3, 0, num3); buffer1 = buffer3; return buffer1; private NameValueCollection m_requestParameters; private Uri m_baseAddress; private ICredentials m_credentials = CredentialCache.DefaultCredentials; public ICredentials
47、Credentials get return this.m_credentials; set this.m_credentials = value; public NameValueCollection QueryString get if (this.m_requestParameters = null) this.m_requestParameters = new NameValueCollection(); return this.m_requestParameters; set this.m_requestParameters = value; public string BaseAd
48、dress get if (this.m_baseAddress != null) return this.m_baseAddress.ToString(); return string.Empty; set if (value = null) | (value.Length = 0) this.m_baseAddress = null; else try this.m_baseAddress = new Uri(value); catch (Exception exception1) throw new ArgumentException("value", excepti
49、on1); private Uri GetUri(string path) Uri uri1; try if (this.m_baseAddress != null) uri1 = new Uri(this.m_baseAddress, path); else uri1 = new Uri(path); if (this.m_requestParameters = null) return uri1; StringBuilder builder1 = new StringBuilder(); string text1 = string.Empty; for (int num1 = 0; num
50、1 < this.m_requestParameters.Count; num1+) builder1.Append(text1 + this.m_requestParameters.AllKeysnum1 + "=" + this.m_requestParametersnum1); text1 = "&" UriBuilder builder2 = new UriBuilder(uri1); builder2.Query = builder1.ToString(); uri1 = builder2.Uri; catch (UriForma
51、tException) uri1 = new Uri(Path.GetFullPath(path); return uri1; / <summary> / 测试类 / </summary> class AppTest int _k = 0; int _K = 0; static void Main() AppTest a = new AppTest(); Microshaoft.Utils.HttpWebClient x = new Microshaoft.Utils.HttpWebClient(); a._K = 10; /订阅 DataReceive事件 x.Dat
52、aReceive += new Microshaoft.Utils.HttpWebClient.DataReceiveEventHandler(a.x_DataReceive); /订阅 ExceptionOccurrs事件 x.ExceptionOccurrs += new Microshaoft.Utils.HttpWebClient.ExceptionEventHandler(a.x_ExceptionOccurrs); x.ThreadProcessEnd += new Microshaoft.Utils.HttpWebClient.ThreadProcessEventHandler(
53、a.x_ThreadProcessEnd); string F = "http:/localhost/download/phpMyAdmin-2.6.1-pl2.zip" F = " a._F = F; string f = F.Substring(F.LastIndexOf("/") + 1); /(new System.Threading.Thread(new System.Threading.ThreadStart(new ThreadProcessState(F, "E:temp" + f, 10, x).SThre
54、adProcess).Start(); x.DownloadFile(F, "d:temp" + f, a._K); / x.DownloadFileChunk(F, "E:temp" + f,15,34556); System.Console.ReadLine(); / string uploadfile = "e:test_local.rar" / string str = x.UploadFileEx("http:/localhost/phpmyadmin/uploadaction.php", "POST", uploadfile, "file1"); / System.Console.WriteLine(str); / System.Console.ReadLine(); string bs = "" /
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 汽车定期维护服务报告合同
- 和对方商谈删除合同协议
- 毛巾出租合同协议模板
- 快速赔偿协议书格式
- 正规聘用合同协议模板
- 楼顶水槽施工协议合同协议
- 江苏省南通市如皋市2025年小升初总复习数学精练含解析
- 商场联营健身合同协议
- 陕西省博爱中学2025届初三下学期5月四校联考生物试题试卷含解析
- 商业门面购房合同协议
- 美国特勤局工作总结
- 新版医疗机构消毒技术规范
- 【波司登羽绒服公司员工招聘问题调研8500字】
- 制度梳理表(总表)
- 睾丸肿瘤课件
- 医学伦理审查委员会的组成与职能
- 终端导购培训-高级导购销售培训
- 空调冷却冷冻水管道系统详细的施工方案设计
- 安全运输医疗垃圾的要点
- 关于员工心理健康的重要性
- 刑事案件模拟法庭剧本完整版五篇
评论
0/150
提交评论