设为首页
加入收藏
联系我们
首页 基础教程 技术文档 实例分析 数 据 库 疑难杂症 ASP.NET 七夕许愿树 技术论坛
同学网,基于同学关系的真实社区
<%-- 最新动态 Begin --%> <%-- 最新动态 End --%>
最新文章
 C#摄像头编程实例
 C#下用P2P技术实现点…
 Asp.net(c#)数…
 SQL Server数据…
 .NET牛人应该知道些什…
 NET牛人应该知道些什么
 SQL Server S…
 备份指定表到另一数据库
 SQLSERVER中快速…
 ASP.NET中url传…
 ASP.NET自动给UR…
 ASP.NET 2.0防…
 ASP.NET 2.0 …
 如何解决ASP.net中…
 sql server 与…
<%-- 最新动态 Begin --%> <%-- 最新动态 End --%>
推荐文章
 关于C#中的REF和黓认…
 读书笔记c#高级编程 委…
 【算法】C#快速排序类
 Visual C#的SQ…
 C#中调用API
 Infragistics…
 C#接口转换
 C#读取设备信息
 用.net操作word
 C# MessageBo…
 Visual C#中的数…
 雅虎公司C#笔试题,看看…
 C#.NET使用NHib…
 .net学习之运算符重载…
 Visual C# 3.…
<%-- 最新动态 Begin --%> <%-- 最新动态 End --%>
热门文章
 ADO.Net与ADO在…
 开发ASP.NET下的M…
 用C#+XMI技术进行U…
 什么是虚拟机?
 C#基础全接触
 C#学习第一天
 雅虎公司C#笔试题,看看…
 C#语言初级入门(1)
 C#中利用正则表达式实现…
 远程重启计算机(C#)
 用.net操作word
 什么是B/S三层?
 VB和C# 语法对比图 …
 Visual C#常用函…
 Visual C#的SQ…
Asp.net 2.0 文件下载[支持多线程, 断点续传功能]
阅读正文 文字大小:增大 减小  文字行距:增大 减小   双击自动滚屏
本文由中国C#技术学习中心整理  如果你对本文有不明之处请到技术论坛讨论!

       最近做了个C/S文件下载工具, 支持多任务, 多线程和断点续传功能. 其中部分代码是从网上找来的, 自己改了

许多Thread Bug, 并增加多任务, 断点续传等功能.  

        由于公司具有代码所有权, 不能将源代码共享.  自己对比较Asp.net感兴趣, 业余时间自己做了个简单的, 基于

Asp.net 2.0的, 目前能够执行对一个文件的下载任务, 但已经实现了多线程, 断点续传功能.  根据需要您可以增加

多任务 功能, 分享一下, 互相学习!  互相借鉴!

       时间仓促, 此程序还没有做很多参数方面的优化. 可以作参考用.

              

(二).运行效果

 

(三). 代码

    1. 核心 DownLoadState.cs 文件代码

   1 /// <summary>
   2 /// Author: [ ChengKing(ZhengJian) ] 
   3 /// Blog:   Http://blog.csdn.net/ChengKing
   4 /// 注:从网上找了个优秀代码
   5 /// 扩展如下功能: 
   6 ///   1. 解决一些线程相关的Bug; 
   7 ///   2.扩展用控制文件实现断点续传功能.
   8 /// </summary>
   9 namespace DownLoadComponent
  10 {
  11     /// <summary>
  12     /// 多线程辅助类(Add by ChengKing)
  13     /// </summary>
  14     public class Task
  15     {
  16         string _FromFileName;
  17         string _ToFileName;
  18         int _ThreadNum;
  19 
  20         public Task(string FromFileName, string ToFileName, int ThreadNum)
  21         {
  22             this._FromFileName = FromFileName;
  23             this._ToFileName = ToFileName;
  24             this._ThreadNum = ThreadNum;
  25         }
  26 
  27         public string FromFileName
  28         {
  29             get
  30             {
  31                 return _FromFileName;
  32             }
  33             set
  34             {
  35                 _FromFileName = value;
  36             }
  37         }
  38         public string ToFileName
  39         {
  40             get
  41             {
  42                 return _ToFileName;
  43             }
  44             set
  45             {
  46                 _ToFileName = value;
  47             }
  48         }
  49         public int ThreadNum
  50         {
  51             get
  52             {
  53                 return _ThreadNum;
  54             }
  55             set
  56             {
  57                 _ThreadNum = value;
  58             }
  59         }
  60     }
  61 
  62     /// <summary>
  63     /// 记录下载的字节位置
  64     /// </summary>
  65     public class DownLoadState
  66     {
  67         private string _FileName;
  68 
  69         private string _AttachmentName;
  70         private int _Position;
  71         private string _RequestURL;
  72         private string _ResponseURL;
  73         private int _Length;
  74 
  75         private byte[] _Data;
  76 
  77         public string FileName
  78         {
  79             get
  80             {
  81                 return _FileName;
  82             }
  83         }
  84 
  85         public int Position
  86         {
  87             get
  88             {
  89                 return _Position;
  90             }
  91         }
  92 
  93         public int Length
  94         {
  95             get
  96             {
  97                 return _Length;
  98             }
  99         }
 100 
 101 
 102         public string AttachmentName
 103         {
 104             get
 105             {
 106                 return _AttachmentName;
 107             }
 108         }
 109 
 110         public string RequestURL
 111         {
 112             get
 113             {
 114                 return _RequestURL;
 115             }
 116         }
 117 
 118         public string ResponseURL
 119         {
 120             get
 121             {
 122                 return _ResponseURL;
 123             }
 124         }
 125 
 126 
 127         public byte[] Data
 128         {
 129             get
 130             {
 131                 return _Data;
 132             }
 133         }
 134 
 135         internal DownLoadState(string RequestURL, string ResponseURL, string FileName, string AttachmentName, int Position, int Length, byte[] Data)
 136         {
 137             this._FileName = FileName;
 138             this._RequestURL = RequestURL;
 139             this._ResponseURL = ResponseURL;
 140             this._AttachmentName = AttachmentName;
 141             this._Position = Position;
 142             this._Data = Data;
 143             this._Length = Length;
 144         }
 145 
 146         internal DownLoadState(string RequestURL, string ResponseURL, string FileName, string AttachmentName, int Position, int Length, ThreadCallbackHandler tch)
 147         {
 148             this._RequestURL = RequestURL;
 149             this._ResponseURL = ResponseURL;
 150             this._FileName = FileName;
 151             this._AttachmentName = AttachmentName;
 152             this._Position = Position;
 153             this._Length = Length;
 154             this._ThreadCallback = tch;
 155         }
 156 
 157         internal DownLoadState(string RequestURL, string ResponseURL, string FileName, string AttachmentName, int Position, int Length)
 158         {
 159             this._RequestURL = RequestURL;
 160             this._ResponseURL = ResponseURL;
 161             this._FileName = FileName;
 162             this._AttachmentName = AttachmentName;
 163             this._Position = Position;
 164             this._Length = Length;
 165         }
 166 
 167         private ThreadCallbackHandler _ThreadCallback;
 168 
 169         //
 170         internal void StartDownloadFileChunk()
 171         {
 172             if (this._ThreadCallback != null)
 173             {
 174                 this._ThreadCallback(this._RequestURL, this._FileName, this._Position, this._Length);
 175             }
 176         }
 177 
 178     }
 179 
 180     //委托代理线程的所执行的方法签名一致
 181     public delegate void ThreadCallbackHandler(string S, string s, int I, int i);
 182 
 183     //异常处理动作
 184     public enum ExceptionActions
 185     {
 186         Throw,
 187         CancelAll,
 188         Ignore,
 189         Retry
 190     }
 191 
 192     /// <summary>
 193     /// 包含 Exception 事件数据的类
 194     /// </summary>
 195     public class ExceptionEventArgs : System.EventArgs
 196     {
 197         private System.Exception _Exception;
 198         private ExceptionActions _ExceptionAction;
 199 
 200         private DownLoadState _DownloadState;
 201 
 202         public DownLoadState DownloadState
 203         {
 204             get
 205             {
 206                 return _DownloadState;
 207             }
 208         }
 209 
 210         public Exception Exception
 211         {
 212             get
 213             {
 214                 return _Exception;
 215             }
 216         }
 217 
 218         public ExceptionActions ExceptionAction
 219         {
 220             get
 221             {
 222                 return _ExceptionAction;
 223             }
 224             set
 225             {
 226                 _ExceptionAction = value;
 227             }
 228         }
 229 
 230         internal ExceptionEventArgs(System.Exception e, DownLoadState DownloadState)
 231         {
 232             this._Exception = e;
 233             this._DownloadState = DownloadState;
 234         }
 235     }
 236 
 237     /// <summary>
 238     /// 包含 DownLoad 事件数据的类
 239     /// </summary>
 240     public class DownLoadEventArgs : System.EventArgs
 241     {
 242         private DownLoadState _DownloadState;
 243 
 244         public DownLoadState DownloadState
 245         {
 246             get
 247             {
 248                 return _DownloadState;
 249             }
 250         }
 251 
 252         public DownLoadEventArgs(DownLoadState DownloadState)
 253         {
 254             this._DownloadState = DownloadState;
 255         }
 256 
 257     }
 258 
 259     /// <summary>
 260     /// 支持断点续传多线程下载的类
 261     /// </summary>
 262     public class HttpWebClient
 263     {
 264         private static object _SyncLockObject = new object();
 265 
 266         public delegate void DataReceiveEventHandler(HttpWebClient Sender, DownLoadEventArgs e);
 267 
 268         public event DataReceiveEventHandler DataReceive; //接收字节数据事件
 269 
 270         public delegate void ExceptionEventHandler(HttpWebClient Sender, ExceptionEventArgs e);
 271 
 272         public event ExceptionEventHandler ExceptionOccurrs; //发生异常事件
 273 
 274         private int _FileLength; //下载文件的总大小
 275 
 276         public static ArrayList threads;
 277 
 278         public int FileLength
 279         {
 280             get
 281             {
 282                 return _FileLength;
 283             }
 284         }
 285 
 286         /// <summary>
 287         /// 分块下载文件
 288         /// </summary>
 289         /// <param name="Address">URL 地址</param>
 290         /// <param name="FileName">保存到本地的路径文件名</param>
 291         /// <param name="ChunksCount">块数,线程数</param>
 292         public void DownloadFile(string Address, string FileName, int ChunksCount)
 293         {
 294             int p = 0// position
 295             int s = 0// chunk size
 296             string a = null;
 297             HttpWebRequest hwrq;
 298             HttpWebResponse hwrp = null;
 299             try
 300             {
 301 
 302                 hwrq = (HttpWebRequest)WebRequest.Create(this.GetUri(Address));
 303                 //hwrq.Timeout = 20000000;
 304                 //if (hwrq.HaveResponse == false)
 305                 //    return;
 306                 //hwrq.ProtocolVersion =HttpVersion.Version10;
 307                 //WebProxy wp = WebProxy.GetDefaultProxy();
 308                 //hwrq.Proxy = wp;
 309                 hwrq.Method = "GET";
 310                 try
 311                 {
 312                     hwrp = (HttpWebResponse)hwrq.GetResponse();
 313                 }
 314                 catch (Exception e)
 315                 {
 316                     throw new Exception(e.Message);
 317                 }
 318 
 319                 long L = hwrp.ContentLength;
 320 
 321                 //如果文件太小, 就不用分多线程, 用一个线程下载即可. (目前控制在800K) 
 322                 //if (L < 800000)
 323                 //{
 324                 //    ChunksCount = 1;
 325                 //}
 326 
 327                 hwrq.Credentials = this.m_credentials;
 328 
 329                 L = ((L == -1|| (L > 0x7fffffff)) ? ((long)0x7fffffff) : L; //Int32.MaxValue 该常数的值为 2,147,483,647; 即十六进制的 0x7FFFFFFF
 330 
 331                 int l = (int)L;
 332 
 333                 this._FileLength = l;
 334 
 335                 bool b = (hwrp.Headers["Accept-Ranges"!= null & hwrp.Headers["Accept-Ranges"== "bytes");
 336                 a = hwrp.Headers["Content-Disposition"]; //attachment
 337                 if (a != null)
 338                 {
 339                     a = a.Substring(a.LastIndexOf("filename="+ 9);
 340                 }
 341                 else
 342                 {
 343                     a = FileName;
 344                 }
 345 
 346                 int ss = s;
 347                 if (b)
 348                 {
 349                     if (ExistControlFile(FileName)) //是否存在文件
 350                     {
 351                         string[] strBlocks = this.ReadInfFromControlFile(FileName).Split(new char[2] { '\r''\n' });
 352                         for (int i = 0; i < strBlocks.Length; i++)
 353                         {
 354                             if (strBlocks[i].Trim().Length != 0 && strBlocks[i].Substring(strBlocks[i].Length - 1== "0")
 355                             {
 356                                 string[] strRecord = strBlocks[i].Split(',');
 357                                 int p2 = int.Parse(strRecord[0]);
 358                                 int s2 = int.Parse(strRecord[1]);
 359                                 DownLoadState x = new DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a, p2, s2, new ThreadCallbackHandler(this.DownloadFileChunk));
 360                                 Thread t = new Thread(new ThreadStart(x.StartDownloadFileChunk));
 361                                 if (threads == null)
 362                                 {
 363                                     threads = new ArrayList();
 364                                 }
 365                                 threads.Add(t);
 366                                 t.Start();
 367                             }
 368 
 369 
 370                         }
 371 
 372                     }
 373                     else
 374                     {
 375                         //建立控制文件
 376                         FileStream fs = File.Create(this.GetControlFileName(FileName));
 377                         fs.Close();
 378 
 379                         if (File.Exists(FileName))
 380                         {
 381                             FileInfo fi = new FileInfo(FileName);
 382                             if (fi.Length == L)
 383                             {
 384                                 this.AddendInfToControlFile(FileName, 0