/* .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (C# DIY HttpWebClient) 
 * Reflector 了一下 System.Net.WebClient ,改写或增加了若干: 
 * DownLoad、Upload 相关方法! 
 * DownLoad 相关改动较大! 
 * 增加了 DataReceive、ExceptionOccurrs 事件! 
 * 了解服务器端与客户端交互的 HTTP 协议参阅: 
 * 使文件下载的自定义连接支持 FlashGet 的断点续传多线程链接下载! JSP/Servlet 实现! 
 * 
http://blog.csdn.net/playyuer/archive/2004/08/02/58430.aspx 
 * 使文件下载的自定义连接支持 FlashGet 的断点续传多线程链接下载! C#/ASP.Net 实现!  
 * 
http://blog.csdn.net/playyuer/archive/2004/08/02/58281.aspx 
 
*/
 
 

2005-03-14 修订: 

/* .Net/C#: 实现支持断点续传多线程下载的工具类 
 * Reflector 了一下 System.Net.WebClient ,改写或增加了若干: 
 * DownLoad、Upload 相关方法! 
 * 增加了 DataReceive、ExceptionOccurrs 事件 
 
*/
 

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

    
return _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._FileName = 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 Position, 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, string 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 _ThreadCallback;

  
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._ThreadCallback(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> 
 
/// 包含 Exception 事件数据的类 
 
/// </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 
   

    
return _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 事件数据的类 
 
/// </summary> 

 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.EventArgs 
 

  
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 DataReceiveEventHandler(HttpWebClient Sender, DownLoadEventArgs e);

  
public event DataReceiveEventHandler DataReceive; //接收字节数据事件

  
public delegate void ExceptionEventHandler(HttpWebClient Sender, ExceptionEventArgs e);

  
public event ExceptionEventHandler ExceptionOccurrs; //发生异常事件

  
public delegate void ThreadProcessEventHandler(HttpWebClient Sender, ThreadProcessEventArgs e);

  
public event ThreadProcessEventHandler ThreadProcessEnd; //发生多线程处理完毕事件


  
private int _FileLength; //下载文件的总大小 

  
public int FileLength 
  

   
get 
   

    
return _FileLength; 
   }
 
  }
 

  
/// <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)) ? ((long0x7fffffff) : L; //Int32.MaxValue 该常数的值为 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 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 < 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.StartDownloadFileChunk(); 

       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) 
     
//    { 
     
//     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 void OnThreadProcess(Thread t) 
  

   
if (ThreadProcessEnd != null
   

    ThreadProcessEventArgs tpea 
= new ThreadProcessEventArgs(t); 
    ThreadProcessEnd(
this, tpea); 
   }
 
  }
 

  
/// <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//整个文件的位置指针 
   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 = 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); 
    }
 
    
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) 
     
//    { 
     
//     this._bytes += num2; 
     
//    } 
     if (num2 > 0
     

      
if (this.DataReceive != null
      

       
byte[] buffer = new byte[num2]; 
       Buffer.BlockCopy(buffer1, p, buffer, 
0, buffer.Length); 
       DownLoadState dls 
= new DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, num2, buffer); 
       DownLoadEventArgs dlea 
= 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 byte[num3]; 
     Buffer.BlockCopy(buffer1, 
0, buffer3, 0, num3); 
     buffer1 
= buffer3; 
    }
 
    
return 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, eea); 
     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[] UploadFile(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 byte[] 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 
= 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 string[7{"--", text1, " Content-Disposition: form-data; name="" + fieldName + ""; filename="", Path.GetFileName(fileName), "" Content-Type: ", text2, " "}
    
string text3 = string.Concat(textArray1); 
    
byte[] buffer1 = Encoding.UTF8.GetBytes(text3); 
    
byte[] buffer2 = Encoding.ASCII.GetBytes(" --" + text1 + " "); 
    
long num1 = 0x7fffffffffffffff
    
try 
    

     num1 
= stream1.Length; 
     request1.ContentLength 
= (num1 + buffer1.Length) + buffer2.Length; 
    }
 
    
catch 
    

    }
 
    
byte[] buffer3 = new byte[Math.Min(0x2000, (int) num1)]; 
    
using (Stream stream2 = request1.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 
= request1.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); 
     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 
= 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.Close(); 
   
if (flag1) 
   

    
byte[] buffer3 = new byte[num3]; 
    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 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 BaseAddress 
  

   
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", exception1); 
     }
 
    }
 
   }
 
  }
 

  
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; num1 < this.m_requestParameters.Count; num1++
    

     builder1.Append(text1 
+ this.m_requestParameters.AllKeys[num1] + "=" + this.m_requestParameters[num1]); 
     text1 
= "&"
    }
 
    UriBuilder builder2 
= new UriBuilder(uri1); 
    builder2.Query 
= builder1.ToString(); 
    uri1 
= builder2.Uri; 
   }
 
   
catch (UriFormatException) 
   

    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.DataReceive += 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(a.x_ThreadProcessEnd); 
  
string F = "http://localhost/download/phpMyAdmin-2.6.1-pl2.zip"
  a._F 
= F; 
  F 
= "http://localhost/download/jdk-1_5_0_01-windows-i586-p.aa.exe"


  
string f = F.Substring(F.LastIndexOf("/"+ 1); 

  
//(new System.Threading.Thread(new System.Threading.ThreadStart(new ThreadProcessState(F, @"E: emp" + f, 10, x).StartThreadProcess))).Start();

  x.DownloadFile(F, 
@"E: emp emp" + f, a._K); 
  
//  x.DownloadFileChunk(F, @"E: emp" + 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 = ""//用于记录上次的位数 
 bool b = false
 
private int i = 0
 
private static object _SyncLockObject = new object(); 
 
string _F; 
 
string _f; 

 
private void x_DataReceive(Microshaoft.Utils.HttpWebClient Sender, Microshaoft.Utils.DownLoadEventArgs e) 
 

  
if (!this.b) 
  

   
lock (_SyncLockObject) 
   

    
if (!this.b) 
    

     System.Console.Write(System.DateTime.Now.ToString() 
+ " 已接收数据:           "); 
     
//System.Console.Write( System.DateTime.Now.ToString() + " 已接收数据:           "); 
     this.b = true
    }
 
   }
 
  }
 
  
string f = e.DownloadState.FileName; 
  
if (e.DownloadState.AttachmentName != null
   f 
= System.IO.Path.GetDirectoryName(f) + @"" + e.DownloadState.AttachmentName; 

  
this._f = f;

  
using (System.IO.FileStream sw = new System.IO.FileStream(f, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, System.IO.FileShare.ReadWrite)) 
  

   sw.Position 
= e.DownloadState.Position; 
   sw.Write(e.DownloadState.Data, 
0, e.DownloadState.Data.Length); 
   sw.Close(); 
  }
 
  
string s = System.DateTime.Now.ToString(); 
  
lock (_SyncLockObject) 
  

   
this.i += e.DownloadState.Data.Length; 
   System.Console.Write(bs 
+ "" + i + " / " + Sender.FileLength + " 字节数据 " + s); 
   
//System.Console.Write(bs + i + " 字节数据 " + s); 
   this.bs = new string('', Digits(i) + 3 + Digits(Sender.FileLength) + s.Length); 
  }
 
 }
 

 
int Digits(int n) //数字所占位数 
 
  n 
= System.Math.Abs(n); 
  n 
= n / 10
  
int i = 1
  
while (n > 0
  

   n 
= n / 10
   i
++
  }
 
  
return i; 
 }
 

 
private void x_ExceptionOccurrs(Microshaoft.Utils.HttpWebClient Sender, Microshaoft.Utils.ExceptionEventArgs e) 
 

  System.Console.WriteLine(e.Exception.Message); 
  
//发生异常重新下载相当于断点续传,你可以自己自行选择处理方式 
  Microshaoft.Utils.HttpWebClient x = new Microshaoft.Utils.HttpWebClient(); 
  x.DownloadFileChunk(
this._F, this._f, e.DownloadState.Position, e.DownloadState.Length); 
  e.ExceptionAction 
= Microshaoft.Utils.ExceptionActions.Ignore; 
 }
 

 
private void x_ThreadProcessEnd(Microshaoft.Utils.HttpWebClient Sender, Microshaoft.Utils.ThreadProcessEventArgs e) 
 

  
//if (e.thread.ThreadState == System.Threading.ThreadState.Stopped) 
  if (this._k ++ == this._K - 1
   System.Console.WriteLine(
" end"); 
 }
 
}
 
 

本文转载:CSDN博客