/// <summary> /// 下载一个文件块,利用该方法可自行实现多线程断点续传 /// </summary> /// <param name="Address">URL 地址</param> /// <param name="FileName">保存到本地的路径文件名</param> /// <param name="Length">块大小</param> 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; hwrq.AddRange(FromPosition); 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 (_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 ExceptionEventArgs(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 Response, long Length, string FileName) { string a = null; //AttachmentName int P = 0; //整个文件的位置指针 long num = 0; try { a = Response.Headers["Content-Disposition"]; //attachment if (a != null) { a = a.Substring(a.LastIndexOf("filename=") + 9); } num = Length; //Response.ContentLength; bool flag = false; if (num == -1) { flag = true; num = 0x0000; //6k } byte[] buffer = new byte[(int)num]; int p = 0; //本块的位置指针 string s = Response.Headers["Content-Range"]; if (s != null) { s = s.Replace("bytes ", ""); s = s.Substring(0, s.IndexOf("-")); P = Convert.Toint(s); } num = 0; Stream S = Response.GetResponseStream(); do { num = S.Read(buffer, num, ((int)num) - num); num += num; if (flag && (num == num)) { num += 0x0000; byte[] buffer = new byte[(int)num]; Buffer.BlockCopy(buffer, 0, buffer, 0, num); buffer = buffer; } // lock (_SyncLockObject) // { // this._bytes += num; // } if (num > 0) { if (this.DataReceive != null) { byte[] buffer = new byte[num]; Buffer.BlockCopy(buffer, p, buffer, 0, buffer.Length); DownLoadState dls = new DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, num, buffer); DownLoadEventArgs dlea = new DownLoadEventArgs(dls); //触发事件 this.OnDataReceive(dlea); //System.Threading.Thread.Sleep(00); } p += num; //本块的位置指针 P += num; //整个文件的位置指针 } else { break; } }while (num != 0); S.Close(); S = null; if (flag) { byte[] buffer = new byte[num]; Buffer.BlockCopy(buffer, 0, buffer, 0, num); buffer = buffer; } return(buffer); } catch (Exception e) { ExceptionActions ea = ExceptionActions.Throw; if (this.ExceptionOccurrs != null) { DownLoadState x = new DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, num); ExceptionEventArgs eea = new ExceptionEventArgs(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; } return(null); } }
/// <summary> /// 分块下载文件 /// </summary> /// <param name="Address">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; HttpWebRequest 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; //Int.MaxValue 该常数的值为 ,7,8,67; 即十六进制的 0x7FFFFFFF int l = (int)L; this._FileLength = l; // 在本地预定空间(竟然在多线程下不用先预定空间) // FileStream sw = new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); // sw.Write(new byte[l], 0, l); // sw.Close(); // sw = null; bool b = (hwrp.Headers["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 < 0x60) //块大小至少为 8 K 字节 { s = 0x60; } 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.StartDownloadFileChunk(); //多线程下载 //Thread t = new Thread(new ThreadStart(x.StartDownloadFileChunk)).Start(); //t.Start(); } p += s; } s = ss; byte[] buffer = this.ResponseAsBytes(Address, hwrp, s, FileName); // lock (_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, p, s); ExceptionEventArgs eea = new ExceptionEventArgs(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 ExceptionEventArgs(System.Exception e, DownLoadState DownloadState) { this._Exception = e; this._DownloadState = DownloadState; }
public DownLoadEventArgs(DownLoadState DownloadState) { this._DownloadState = DownloadState; }
internal byte[] ResponseAsBytes(string RequestURL, WebResponse Response, long Length, string FileName) { string a = null; //AttachmentName int P = 0; //整个文件的位置指针 long num = 0; try { a = Response.Headers["Content-Disposition"]; //attachment if (a != null) { a = a.Substring(a.LastIndexOf("filename=") + 9); } num = Length; //Response.ContentLength; bool flag = false; if (num == -1) { flag = true; num = 0x0000; //6k } byte[] buffer = new byte[(int)num]; int p = 0; //本块的位置指针 string s = Response.Headers["Content-Range"]; if (s != null) { s = s.Replace("bytes ", ""); s = s.Substring(0, s.IndexOf("-")); P = Convert.Toint(s); } num = 0; Stream S = Response.GetResponseStream(); do { num = S.Read(buffer, num, ((int)num) - num); num += num; if (flag && (num == num)) { num += 0x0000; byte[] buffer = new byte[(int)num]; Buffer.BlockCopy(buffer, 0, buffer, 0, num); buffer = buffer; } // lock (_SyncLockObject) // { // this._bytes += num; // } if (num > 0) { if (this.DataReceive != null) { byte[] buffer = new byte[num]; Buffer.BlockCopy(buffer, p, buffer, 0, buffer.Length); DownLoadState dls = new DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, num, buffer); DownLoadEventArgs dlea = new DownLoadEventArgs(dls); //触发事件 this.OnDataReceive(dlea); //System.Threading.Thread.Sleep(00); } p += num; //本块的位置指针 P += num; //整个文件的位置指针 } else { break; } } while (num != 0); S.Close(); S = null; if (flag) { byte[] buffer = new byte[num]; Buffer.BlockCopy(buffer, 0, buffer, 0, num); buffer = buffer; } return buffer; } catch (Exception e) { ExceptionActions ea = ExceptionActions.Throw; if (this.ExceptionOccurrs != null) { DownLoadState x = new DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, num); ExceptionEventArgs eea = new ExceptionEventArgs(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; } return null; } }