前些时间写的一个下载类,支持断点下载,多线程之类的,折腾了点时间才写出来
是用于在线更新的
写的不够好的地方希望大家提出来,我会继续改正
可能一下代码会比较长,看起来比较麻烦,我大概说一下用法,这个类我自己测试过是没有问题的
代码
1 Download load = new Download(dr["SourceUrl"].ToString());
2 load.ThreadCount = 5;
3 load.Filename = dr["FileName"].ToString();
4 load.DirectoryName = dr["Dest"].ToString();
5 load.Progress += new Download.ProgressEventHandler(load_Progress);
6 load.Finished += new Download.FinishedEventHandler(load_Finished);
7 load.Speed += new Download.SpeedHandler(load_Speed);
8 load.Start();
2 load.ThreadCount = 5;
3 load.Filename = dr["FileName"].ToString();
4 load.DirectoryName = dr["Dest"].ToString();
5 load.Progress += new Download.ProgressEventHandler(load_Progress);
6 load.Finished += new Download.FinishedEventHandler(load_Finished);
7 load.Speed += new Download.SpeedHandler(load_Speed);
8 load.Start();
下面是全部代码
Download
1 public class Download
2 {
3 public Download(string url)
4 {
5 this.Url = url;
6 this.ThreadCount = 5;
7 }
8
9 #region 委托
10
11 public delegate void ExceptionEventHandler(Download sender, Exception e);
12 public delegate void ConnectedEventHandler(Download sender, string filename, string contentType);
13 public delegate void ProgressEventHandler(Download sender);
14 public delegate void FinishedEventHandler(Download sender);
15 public delegate void SpeedHandler(Download sender);
16
17 #endregion
18
19 #region 成员
20
21 private ExceptionEventHandler _exception;
22 private ConnectedEventHandler _connected;
23 private ProgressEventHandler _progress;
24 private FinishedEventHandler _finished;
25 private SpeedHandler _speed;
26
27 private Thread thConnection;
28 private Thread[] thDownloads;
29 private Stream fileStream;
30 private object lockFinishedLength = new object();
31 private int postion = 2 * 2 * 64 * 1024;//块大小
32
33 private Dictionary<string, int> SpeedDic = new Dictionary<string, int>();
34
35 private string ConfigFile = "";
36 #endregion
37
38 #region 属性
39
40 /// <summary>
41 /// 下载线程数量
42 /// </summary>
43 public int ThreadCount { get; set; }
44
45 /// <summary>
46 /// 下载资源位置
47 /// </summary>
48 public string Url { get; set; }
49
50 /// <summary>
51 /// 资源保存路径
52 /// </summary>
53 public string Filename { get; set; }
54
55 /// <summary>
56 /// 资源长度
57 /// </summary>
58 public long ContentLength { get; private set; }
59
60 /// <summary>
61 /// 资源已下载长度
62 /// </summary>
63 public long FinishedLength { get; private set; }
64
65 /// <summary>
66 /// 下载百分比
67 /// </summary>
68 public int FinishedRate { get; private set; }
69
70 /// <summary>
71 /// 文件夹
72 /// </summary>
73 public string DirectoryName { get; set; }
74
75 /// <summary>
76 /// 进度条
77 /// </summary>
78 public object ProgressBar { get; set; }
79
80 /// <summary>
81 /// 控件
82 /// </summary>
83 public object Control { get; set; }
84
85 /// <summary>
86 /// 速度
87 /// </summary>
88 public string SpeedStr { get; private set; }
89
90 #endregion
91
92 #region 事件
93
94 /// <summary>
95 /// 当连接上资源后发生
96 /// </summary>
97 public event ConnectedEventHandler Connected
98 {
99 add
100 {
101 this._connected += value;
102 }
103 remove
104 {
105 this._connected -= value;
106 }
107 }
108
109 /// <summary>
110 /// 当连下载进度变化后发生
111 /// </summary>
112 public event ProgressEventHandler Progress
113 {
114 add
115 {
116 this._progress += value;
117 }
118 remove
119 {
120 this._progress -= value;
121 }
122 }
123
124 /// <summary>
125 /// 当下载完成后发生
126 /// </summary>
127 public event FinishedEventHandler Finished
128 {
129 add
130 {
131 this._finished += value;
132 }
133 remove
134 {
135 this._finished -= value;
136 }
137 }
138
139 /// <summary>
140 /// 当连下载发生异常后发生
141 /// </summary>
142 public event ExceptionEventHandler Exception
143 {
144 add
145 {
146 this._exception += value;
147 }
148 remove
149 {
150 this._exception -= value;
151 }
152 }
153
154 /// <summary>
155 /// 速度事件
156 /// </summary>
157 public event SpeedHandler Speed
158 {
159 add
160 {
161 this._speed += value;
162 }
163 remove
164 {
165 this._speed -= value;
166 }
167 }
168
169 #endregion
170
171 #region 响应
172
173 protected void OnConnected(string filename, string contentType)
174 {
175 if (this._connected != null)
176 {
177 this._connected.Invoke(this, filename, contentType);
178 }
179 }
180
181 protected void OnProgress()
182 {
183 // 统计百分比
184 lock (this.lockFinishedLength)
185 {
186 int rate = (int)(this.FinishedLength * 100 / this.ContentLength);
187 if (rate != this.FinishedRate)
188 this.FinishedRate = rate;
189 else
190 return;
191 }
192 // 进度事件处理
193 if (this._progress != null)
194 {
195 lock (this._progress)
196 {
197 this._progress.Invoke(this);
198 }
199 }
200 }
201
202 protected void OnFinished()
203 {
204 bool isFinished = true;
205 lock (this.thDownloads)
206 {
207 foreach (Thread thread in this.thDownloads)
208 {
209 if (thread != null)
210 if (thread.ThreadState != ThreadState.Stopped && thread != Thread.CurrentThread)
211 {
212 isFinished = false;
213 break;
214 }
215 }
216 }
217
218 if (isFinished)
219 {
220 this.fileStream.Close();
221
222 if (File.Exists(this.Filename))
223 {
224 File.Delete(this.Filename);
225 }
226 File.Move(this.Filename + ".tfg", this.Filename);
227
228 if (File.Exists(ConfigFile))
229 {
230 File.Delete(ConfigFile);
231 }
232
233 if (this._finished != null)
234 {
235 this._finished.Invoke(this);
236 }
237 }
238 }
239
240 protected void OnException(Exception e)
241 {
242 this.Abort();
243
244 if (this._exception != null)
245 {
246 this._exception.Invoke(this, e);
247 }
248 }
249
250 protected void OnSpeed()
251 {
252 int result = 0;
253 lock (SpeedDic)
254 {
255 foreach (string key in SpeedDic.Keys)
256 {
257 result += SpeedDic[key];
258 }
259 }
260 SpeedStr = result.ToString("f0") + "KB/s";
261 if (this._speed != null)
262 {
263 lock (this._speed)
264 {
265 this._speed.Invoke(this);
266 }
267 }
268 }
269
270 #endregion
271
272 #region 方法
273
274 /// <summary>
275 /// 开始下载
276 /// </summary>
277 public void Start()
278 {
279 if (thConnection == null)
280 {
281 this.thConnection = new Thread(new ThreadStart(this.Connection));
282 this.thConnection.Start();
283 }
284 }
285
286 /// <summary>
287 /// 停止下载
288 /// </summary>
289 public void Stop()
290 {
291 // 停止连接
292 if (this.thConnection != null)
293 {
294 this.thConnection.Abort();
295 this.thConnection.Join();
296 }
297 // 停止下载
298 this.Abort();
299 // 释放资源
300 if (this.fileStream != null)
301 {
302 this.fileStream.Dispose();
303 }
304 }
305
306 /// <summary>
307 /// 终止下载线程
308 /// </summary>
309 private void Abort()
310 {
311 if (this.thDownloads != null)
312 {
313 lock (this.thDownloads)
314 {
315 foreach (Thread thread in this.thDownloads)
316 {
317 if (thread != Thread.CurrentThread)
318 {
319 thread.Abort();
320 thread.Join();
321 }
322 }
323 }
324 }
325 }
326
327 /// <summary>
328 /// 资源连接(读取资源长度,文件名称)
329 /// </summary>
330 private void Connection()
331 {
332 try
333 {
334 // 请求
335 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(this.Url);
336 request.Method = "Head";
337 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
338 this.ContentLength = response.ContentLength;
339 string filename = this.GetFilename(response.GetResponseHeader("Content-Disposition"));
340 response.Close();
341
342 this.OnConnected(filename, response.ContentType);
343
344 if (this.ContentLength == 0)
345 {
346 this.OnFinished();
347 return;
348 }
349
350 // 下载
351 if (this.ThreadCount < 1 || this.ThreadCount > 100)
352 {
353 throw new Exception("无效的线程数量");
354 }
355
356 if (!Directory.Exists(DirectoryName))
357 {
358 Directory.CreateDirectory(DirectoryName);
359 }
360
361 this.Filename = DirectoryName + "\\" + Filename;
362
363 ConfigFile = Filename + ".cfg";
364
365 #region [ 创建控制文件和空白文件 ]
366 if (!File.Exists(ConfigFile))
367 {
368 WriteConfigFile();
369 byte[] emptyByte = new byte[ContentLength];
370 FileStream fs = new FileStream(this.Filename + ".tfg", FileMode.Create, FileAccess.Write);
371 fs.Write(emptyByte, 0, emptyByte.Length);
372 fs.Dispose();
373 fs.Close();
374 }
375 #endregion
376
377 #region [ 下载断点 ]
378 ArrayList MustDoan = new ArrayList();
379 int complete = 0;
380 string[] strBlocks = ReadConfigFile().Split(new char[2] { '\r', '\n' });
381 for (int j = 0; j < strBlocks.Length; j++)
382 {
383 if (strBlocks[j].Trim().Length != 0 && strBlocks[j].Substring(strBlocks[j].Length - 1) == "0")
384 {
385 MustDoan.Add(strBlocks[j].Trim());
386 }
387 else if (strBlocks[j].Trim().Length != 0 && strBlocks[j].Substring(strBlocks[j].Length - 1) == "1")
388 {
389 complete++;
390 }
391 }
392 this.FinishedLength = complete * postion;
393 #endregion
394
395 this.fileStream = new FileStream(this.Filename + ".tfg", FileMode.Open, FileAccess.Write);
396
397 this.thDownloads = new Thread[this.ThreadCount];
398 int arrLen = MustDoan.Count;
399 int modNum = arrLen / ThreadCount;
400 int endNum = modNum + arrLen % ThreadCount;
401 // int modNum = (int)(this.ContentLength / this.thDownloads.Length);
402 for (int i = 0; i < thDownloads.Length; i++)
403 {
404 int from = i * modNum;
405 //int to = (i == thDownloads.Length - 1) ? (int)this.ContentLength : from + modNum;
406 int to = from + (i == ThreadCount - 1 ? endNum : modNum);
407 this.thDownloads[i] = new Thread(new ParameterizedThreadStart(this.DownloadBlock));
408 this.thDownloads[i].Name = "T" + i;
409 this.thDownloads[i].Start(new object[] { from, to, MustDoan });
410 }
411 }
412 catch (Exception e)
413 {
414 if (!(e is ThreadAbortException))
415 {
416 this.OnException(e);
417 }
418 }
419 }
420
421 /// <summary>
422 /// 下载数据
423 /// </summary>
424 private void DownloadBlock(object rang)
425 {
426 int from = Convert.ToInt32((rang as object[])[0]);
427 int to = Convert.ToInt32((rang as object[])[1]);
428 ArrayList MustDoan = (rang as object[])[2] as ArrayList;
429
430 HttpWebRequest hwRequest = null;
431 HttpWebResponse hwResponse = null;
432 Stream responseStream = null;
433 while (from < to)
434 {
435 string[] strRecord = MustDoan[from].ToString().Split(',');
436 int reStart = int.Parse(strRecord[0]);
437 int reEnd = int.Parse(strRecord[1]);
438 try
439 {
440 hwRequest = (HttpWebRequest)HttpWebRequest.Create(this.Url);
441 hwRequest.AddRange(reStart, reStart + reEnd);
442 hwResponse = (HttpWebResponse)hwRequest.GetResponse();
443 responseStream = hwResponse.GetResponseStream();
444
445 byte[] buffer = new byte[1024 * 10];
446 int size = 0, count = 0;
447 TimeSpan tsBegin;
448 DateTime dtBegin = DateTime.Now;
449 int secondSize = size;
450 do
451 {
452 DateTime dtEnd = DateTime.Now;
453 tsBegin = dtEnd - dtBegin;
454 if (tsBegin.TotalSeconds >= 1)
455 {
456 dtBegin = DateTime.Now;
457 double totalSecond = tsBegin.TotalSeconds;
458 double speed = secondSize / (totalSecond * 1024);
459 SetSpeed(Thread.CurrentThread.Name, (int)speed);
460 secondSize = 0;
461 }
462
463 size = responseStream.Read(buffer, 0, buffer.Length);
464 lock (this.lockFinishedLength)
465 {
466 this.FinishedLength += size;
467 }
468
469 lock (this.fileStream)
470 {
471 this.fileStream.Seek(reStart + count, SeekOrigin.Begin);
472 this.fileStream.Write(buffer, 0, size);
473 }
474
475 UpdateConfigFile(MustDoan[from].ToString());
476
477 secondSize += size;
478 reStart += size;
479 this.OnProgress();
480 this.OnSpeed();
481
482 } while (size > 0);
483 }
484 catch (Exception e)
485 {
486 if (!(e is ThreadAbortException))
487 {
488 this.OnException(e);
489 }
490 }
491 finally
492 {
493 if (responseStream != null)
494 {
495 responseStream.Close();
496 }
497 if (hwResponse != null)
498 {
499 hwResponse.Close();
500 }
501 }
502 from++;
503 }
504
505 this.OnFinished();
506 }
507
508 /// <summary>
509 /// 得到文件名称
510 /// </summary>
511 private string GetFilename(string contentDisposition)
512 {
513 string filename = "";
514 if (contentDisposition.IndexOf("filename=") != -1)
515 {
516 filename = filename.Substring(filename.IndexOf("filename=") + 9);
517 }
518 else
519 {
520 filename = this.Url.Substring(this.Url.LastIndexOf("/") + 1);
521 }
522 return filename;
523 }
524
525 /// <summary>
526 /// 创建控制文件
527 /// </summary>
528 private void WriteConfigFile()
529 {
530 StreamWriter sw = new StreamWriter(ConfigFile);
531 int p = 0;
532 int l = (int)this.ContentLength;
533 int m = postion;
534 while (l >= m)
535 {
536 l -= m;
537 if (l < m)
538 {
539 m += l;
540 }
541 sw.WriteLine(p.ToString() + "," + m.ToString() + "," + "0");
542 p += m;
543 }
544 sw.Dispose();
545 sw.Close();
546 }
547
548 /// <summary>
549 /// 读取控制文件
550 /// </summary>
551 /// <returns></returns>
552 public string ReadConfigFile()
553 {
554 string result = "";
555 using (StreamReader sr = new StreamReader(ConfigFile))
556 {
557 result = sr.ReadToEnd().Trim();
558 }
559 return result;
560 }
561
562 /// <summary>
563 /// 更新控制文件
564 /// </summary>
565 /// <param name="str"></param>
566 public void UpdateConfigFile(string str)
567 {
568 lock (ConfigFile)
569 {
570 string s = null;
571 using (StreamReader sr = new System.IO.StreamReader(ConfigFile))
572 {
573 s = sr.ReadToEnd().Trim();
574
575 string[] ss = str.Split(',');
576 s = s.Replace(ss[0] + "," + ss[1] + ",0", ss[0] + "," + ss[1] + ",1");
577 }
578 using (StreamWriter sw = new StreamWriter(ConfigFile, false, Encoding.Default))
579 {
580 sw.WriteLine(s);
581 }
582 }
583 }
584
585 /// <summary>
586 /// SetSpeed
587 /// </summary>
588 /// <param name="threadName"></param>
589 /// <param name="speed"></param>
590 private void SetSpeed(string threadName, int speed)
591 {
592 lock (SpeedDic)
593 {
594 if (SpeedDic.ContainsKey(threadName))
595 SpeedDic[threadName] = speed;
596 else
597 SpeedDic.Add(threadName, speed);
598 }
599 }
600 #endregion
601 }
602
2 {
3 public Download(string url)
4 {
5 this.Url = url;
6 this.ThreadCount = 5;
7 }
8
9 #region 委托
10
11 public delegate void ExceptionEventHandler(Download sender, Exception e);
12 public delegate void ConnectedEventHandler(Download sender, string filename, string contentType);
13 public delegate void ProgressEventHandler(Download sender);
14 public delegate void FinishedEventHandler(Download sender);
15 public delegate void SpeedHandler(Download sender);
16
17 #endregion
18
19 #region 成员
20
21 private ExceptionEventHandler _exception;
22 private ConnectedEventHandler _connected;
23 private ProgressEventHandler _progress;
24 private FinishedEventHandler _finished;
25 private SpeedHandler _speed;
26
27 private Thread thConnection;
28 private Thread[] thDownloads;
29 private Stream fileStream;
30 private object lockFinishedLength = new object();
31 private int postion = 2 * 2 * 64 * 1024;//块大小
32
33 private Dictionary<string, int> SpeedDic = new Dictionary<string, int>();
34
35 private string ConfigFile = "";
36 #endregion
37
38 #region 属性
39
40 /// <summary>
41 /// 下载线程数量
42 /// </summary>
43 public int ThreadCount { get; set; }
44
45 /// <summary>
46 /// 下载资源位置
47 /// </summary>
48 public string Url { get; set; }
49
50 /// <summary>
51 /// 资源保存路径
52 /// </summary>
53 public string Filename { get; set; }
54
55 /// <summary>
56 /// 资源长度
57 /// </summary>
58 public long ContentLength { get; private set; }
59
60 /// <summary>
61 /// 资源已下载长度
62 /// </summary>
63 public long FinishedLength { get; private set; }
64
65 /// <summary>
66 /// 下载百分比
67 /// </summary>
68 public int FinishedRate { get; private set; }
69
70 /// <summary>
71 /// 文件夹
72 /// </summary>
73 public string DirectoryName { get; set; }
74
75 /// <summary>
76 /// 进度条
77 /// </summary>
78 public object ProgressBar { get; set; }
79
80 /// <summary>
81 /// 控件
82 /// </summary>
83 public object Control { get; set; }
84
85 /// <summary>
86 /// 速度
87 /// </summary>
88 public string SpeedStr { get; private set; }
89
90 #endregion
91
92 #region 事件
93
94 /// <summary>
95 /// 当连接上资源后发生
96 /// </summary>
97 public event ConnectedEventHandler Connected
98 {
99 add
100 {
101 this._connected += value;
102 }
103 remove
104 {
105 this._connected -= value;
106 }
107 }
108
109 /// <summary>
110 /// 当连下载进度变化后发生
111 /// </summary>
112 public event ProgressEventHandler Progress
113 {
114 add
115 {
116 this._progress += value;
117 }
118 remove
119 {
120 this._progress -= value;
121 }
122 }
123
124 /// <summary>
125 /// 当下载完成后发生
126 /// </summary>
127 public event FinishedEventHandler Finished
128 {
129 add
130 {
131 this._finished += value;
132 }
133 remove
134 {
135 this._finished -= value;
136 }
137 }
138
139 /// <summary>
140 /// 当连下载发生异常后发生
141 /// </summary>
142 public event ExceptionEventHandler Exception
143 {
144 add
145 {
146 this._exception += value;
147 }
148 remove
149 {
150 this._exception -= value;
151 }
152 }
153
154 /// <summary>
155 /// 速度事件
156 /// </summary>
157 public event SpeedHandler Speed
158 {
159 add
160 {
161 this._speed += value;
162 }
163 remove
164 {
165 this._speed -= value;
166 }
167 }
168
169 #endregion
170
171 #region 响应
172
173 protected void OnConnected(string filename, string contentType)
174 {
175 if (this._connected != null)
176 {
177 this._connected.Invoke(this, filename, contentType);
178 }
179 }
180
181 protected void OnProgress()
182 {
183 // 统计百分比
184 lock (this.lockFinishedLength)
185 {
186 int rate = (int)(this.FinishedLength * 100 / this.ContentLength);
187 if (rate != this.FinishedRate)
188 this.FinishedRate = rate;
189 else
190 return;
191 }
192 // 进度事件处理
193 if (this._progress != null)
194 {
195 lock (this._progress)
196 {
197 this._progress.Invoke(this);
198 }
199 }
200 }
201
202 protected void OnFinished()
203 {
204 bool isFinished = true;
205 lock (this.thDownloads)
206 {
207 foreach (Thread thread in this.thDownloads)
208 {
209 if (thread != null)
210 if (thread.ThreadState != ThreadState.Stopped && thread != Thread.CurrentThread)
211 {
212 isFinished = false;
213 break;
214 }
215 }
216 }
217
218 if (isFinished)
219 {
220 this.fileStream.Close();
221
222 if (File.Exists(this.Filename))
223 {
224 File.Delete(this.Filename);
225 }
226 File.Move(this.Filename + ".tfg", this.Filename);
227
228 if (File.Exists(ConfigFile))
229 {
230 File.Delete(ConfigFile);
231 }
232
233 if (this._finished != null)
234 {
235 this._finished.Invoke(this);
236 }
237 }
238 }
239
240 protected void OnException(Exception e)
241 {
242 this.Abort();
243
244 if (this._exception != null)
245 {
246 this._exception.Invoke(this, e);
247 }
248 }
249
250 protected void OnSpeed()
251 {
252 int result = 0;
253 lock (SpeedDic)
254 {
255 foreach (string key in SpeedDic.Keys)
256 {
257 result += SpeedDic[key];
258 }
259 }
260 SpeedStr = result.ToString("f0") + "KB/s";
261 if (this._speed != null)
262 {
263 lock (this._speed)
264 {
265 this._speed.Invoke(this);
266 }
267 }
268 }
269
270 #endregion
271
272 #region 方法
273
274 /// <summary>
275 /// 开始下载
276 /// </summary>
277 public void Start()
278 {
279 if (thConnection == null)
280 {
281 this.thConnection = new Thread(new ThreadStart(this.Connection));
282 this.thConnection.Start();
283 }
284 }
285
286 /// <summary>
287 /// 停止下载
288 /// </summary>
289 public void Stop()
290 {
291 // 停止连接
292 if (this.thConnection != null)
293 {
294 this.thConnection.Abort();
295 this.thConnection.Join();
296 }
297 // 停止下载
298 this.Abort();
299 // 释放资源
300 if (this.fileStream != null)
301 {
302 this.fileStream.Dispose();
303 }
304 }
305
306 /// <summary>
307 /// 终止下载线程
308 /// </summary>
309 private void Abort()
310 {
311 if (this.thDownloads != null)
312 {
313 lock (this.thDownloads)
314 {
315 foreach (Thread thread in this.thDownloads)
316 {
317 if (thread != Thread.CurrentThread)
318 {
319 thread.Abort();
320 thread.Join();
321 }
322 }
323 }
324 }
325 }
326
327 /// <summary>
328 /// 资源连接(读取资源长度,文件名称)
329 /// </summary>
330 private void Connection()
331 {
332 try
333 {
334 // 请求
335 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(this.Url);
336 request.Method = "Head";
337 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
338 this.ContentLength = response.ContentLength;
339 string filename = this.GetFilename(response.GetResponseHeader("Content-Disposition"));
340 response.Close();
341
342 this.OnConnected(filename, response.ContentType);
343
344 if (this.ContentLength == 0)
345 {
346 this.OnFinished();
347 return;
348 }
349
350 // 下载
351 if (this.ThreadCount < 1 || this.ThreadCount > 100)
352 {
353 throw new Exception("无效的线程数量");
354 }
355
356 if (!Directory.Exists(DirectoryName))
357 {
358 Directory.CreateDirectory(DirectoryName);
359 }
360
361 this.Filename = DirectoryName + "\\" + Filename;
362
363 ConfigFile = Filename + ".cfg";
364
365 #region [ 创建控制文件和空白文件 ]
366 if (!File.Exists(ConfigFile))
367 {
368 WriteConfigFile();
369 byte[] emptyByte = new byte[ContentLength];
370 FileStream fs = new FileStream(this.Filename + ".tfg", FileMode.Create, FileAccess.Write);
371 fs.Write(emptyByte, 0, emptyByte.Length);
372 fs.Dispose();
373 fs.Close();
374 }
375 #endregion
376
377 #region [ 下载断点 ]
378 ArrayList MustDoan = new ArrayList();
379 int complete = 0;
380 string[] strBlocks = ReadConfigFile().Split(new char[2] { '\r', '\n' });
381 for (int j = 0; j < strBlocks.Length; j++)
382 {
383 if (strBlocks[j].Trim().Length != 0 && strBlocks[j].Substring(strBlocks[j].Length - 1) == "0")
384 {
385 MustDoan.Add(strBlocks[j].Trim());
386 }
387 else if (strBlocks[j].Trim().Length != 0 && strBlocks[j].Substring(strBlocks[j].Length - 1) == "1")
388 {
389 complete++;
390 }
391 }
392 this.FinishedLength = complete * postion;
393 #endregion
394
395 this.fileStream = new FileStream(this.Filename + ".tfg", FileMode.Open, FileAccess.Write);
396
397 this.thDownloads = new Thread[this.ThreadCount];
398 int arrLen = MustDoan.Count;
399 int modNum = arrLen / ThreadCount;
400 int endNum = modNum + arrLen % ThreadCount;
401 // int modNum = (int)(this.ContentLength / this.thDownloads.Length);
402 for (int i = 0; i < thDownloads.Length; i++)
403 {
404 int from = i * modNum;
405 //int to = (i == thDownloads.Length - 1) ? (int)this.ContentLength : from + modNum;
406 int to = from + (i == ThreadCount - 1 ? endNum : modNum);
407 this.thDownloads[i] = new Thread(new ParameterizedThreadStart(this.DownloadBlock));
408 this.thDownloads[i].Name = "T" + i;
409 this.thDownloads[i].Start(new object[] { from, to, MustDoan });
410 }
411 }
412 catch (Exception e)
413 {
414 if (!(e is ThreadAbortException))
415 {
416 this.OnException(e);
417 }
418 }
419 }
420
421 /// <summary>
422 /// 下载数据
423 /// </summary>
424 private void DownloadBlock(object rang)
425 {
426 int from = Convert.ToInt32((rang as object[])[0]);
427 int to = Convert.ToInt32((rang as object[])[1]);
428 ArrayList MustDoan = (rang as object[])[2] as ArrayList;
429
430 HttpWebRequest hwRequest = null;
431 HttpWebResponse hwResponse = null;
432 Stream responseStream = null;
433 while (from < to)
434 {
435 string[] strRecord = MustDoan[from].ToString().Split(',');
436 int reStart = int.Parse(strRecord[0]);
437 int reEnd = int.Parse(strRecord[1]);
438 try
439 {
440 hwRequest = (HttpWebRequest)HttpWebRequest.Create(this.Url);
441 hwRequest.AddRange(reStart, reStart + reEnd);
442 hwResponse = (HttpWebResponse)hwRequest.GetResponse();
443 responseStream = hwResponse.GetResponseStream();
444
445 byte[] buffer = new byte[1024 * 10];
446 int size = 0, count = 0;
447 TimeSpan tsBegin;
448 DateTime dtBegin = DateTime.Now;
449 int secondSize = size;
450 do
451 {
452 DateTime dtEnd = DateTime.Now;
453 tsBegin = dtEnd - dtBegin;
454 if (tsBegin.TotalSeconds >= 1)
455 {
456 dtBegin = DateTime.Now;
457 double totalSecond = tsBegin.TotalSeconds;
458 double speed = secondSize / (totalSecond * 1024);
459 SetSpeed(Thread.CurrentThread.Name, (int)speed);
460 secondSize = 0;
461 }
462
463 size = responseStream.Read(buffer, 0, buffer.Length);
464 lock (this.lockFinishedLength)
465 {
466 this.FinishedLength += size;
467 }
468
469 lock (this.fileStream)
470 {
471 this.fileStream.Seek(reStart + count, SeekOrigin.Begin);
472 this.fileStream.Write(buffer, 0, size);
473 }
474
475 UpdateConfigFile(MustDoan[from].ToString());
476
477 secondSize += size;
478 reStart += size;
479 this.OnProgress();
480 this.OnSpeed();
481
482 } while (size > 0);
483 }
484 catch (Exception e)
485 {
486 if (!(e is ThreadAbortException))
487 {
488 this.OnException(e);
489 }
490 }
491 finally
492 {
493 if (responseStream != null)
494 {
495 responseStream.Close();
496 }
497 if (hwResponse != null)
498 {
499 hwResponse.Close();
500 }
501 }
502 from++;
503 }
504
505 this.OnFinished();
506 }
507
508 /// <summary>
509 /// 得到文件名称
510 /// </summary>
511 private string GetFilename(string contentDisposition)
512 {
513 string filename = "";
514 if (contentDisposition.IndexOf("filename=") != -1)
515 {
516 filename = filename.Substring(filename.IndexOf("filename=") + 9);
517 }
518 else
519 {
520 filename = this.Url.Substring(this.Url.LastIndexOf("/") + 1);
521 }
522 return filename;
523 }
524
525 /// <summary>
526 /// 创建控制文件
527 /// </summary>
528 private void WriteConfigFile()
529 {
530 StreamWriter sw = new StreamWriter(ConfigFile);
531 int p = 0;
532 int l = (int)this.ContentLength;
533 int m = postion;
534 while (l >= m)
535 {
536 l -= m;
537 if (l < m)
538 {
539 m += l;
540 }
541 sw.WriteLine(p.ToString() + "," + m.ToString() + "," + "0");
542 p += m;
543 }
544 sw.Dispose();
545 sw.Close();
546 }
547
548 /// <summary>
549 /// 读取控制文件
550 /// </summary>
551 /// <returns></returns>
552 public string ReadConfigFile()
553 {
554 string result = "";
555 using (StreamReader sr = new StreamReader(ConfigFile))
556 {
557 result = sr.ReadToEnd().Trim();
558 }
559 return result;
560 }
561
562 /// <summary>
563 /// 更新控制文件
564 /// </summary>
565 /// <param name="str"></param>
566 public void UpdateConfigFile(string str)
567 {
568 lock (ConfigFile)
569 {
570 string s = null;
571 using (StreamReader sr = new System.IO.StreamReader(ConfigFile))
572 {
573 s = sr.ReadToEnd().Trim();
574
575 string[] ss = str.Split(',');
576 s = s.Replace(ss[0] + "," + ss[1] + ",0", ss[0] + "," + ss[1] + ",1");
577 }
578 using (StreamWriter sw = new StreamWriter(ConfigFile, false, Encoding.Default))
579 {
580 sw.WriteLine(s);
581 }
582 }
583 }
584
585 /// <summary>
586 /// SetSpeed
587 /// </summary>
588 /// <param name="threadName"></param>
589 /// <param name="speed"></param>
590 private void SetSpeed(string threadName, int speed)
591 {
592 lock (SpeedDic)
593 {
594 if (SpeedDic.ContainsKey(threadName))
595 SpeedDic[threadName] = speed;
596 else
597 SpeedDic.Add(threadName, speed);
598 }
599 }
600 #endregion
601 }
602