引用命名空间:
using System.Net;//网络功能 using System.IO;//流支持 using System.Threading;//线程支持
定义线程下载主体:
1 public class threadbody 2 { 3 Program p; 4 int i; 5 public threadbody( Program t_p,int t_i) 6 { 7 p = t_p; 8 i = t_i; 9 } 10 11 public void Download() 12 { 13 try 14 { 15 string filename = p.filenamew[i]; 16 FileStream fsteam=new FileStream(filename, System.IO.FileMode.Create); 17 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(p.StrUrl); 18 request.AddRange(p.filestartw[i], p.filestartw[i] + p.filesizew[i]);//设置Range值 19 //向服务器请求,获得服务器回应数据流 20 System.IO.Stream ns = request.GetResponse().GetResponseStream(); 21 byte[] nbytes = new byte[1024]; 22 int nReadSize = 0; 23 nReadSize = ns.Read(nbytes, 0, 1024); 24 while (nReadSize > 0) 25 { 26 fsteam.Write(nbytes, 0, nReadSize); 27 nReadSize = ns.Read(nbytes, 0, 1024); 28 } 29 30 fsteam.Close(); 31 ns.Close(); 32 Console.WriteLine("线程{0}下载完成", i); 33 p.threadw[i] = true;//表明此线程结束。 34 } 35 36 catch (Exception ex) 37 { 38 39 //p.fs.Close(); 40 41 Console.WriteLine("下载过程中出现错误:" + ex.ToString()); 42 43 } 44 45 } 46 }
下载类:
1 public class Program 2 { 3 public int[] filestartw = new int[5];//每个线程接收文件的起始位置 4 public int[] filesizew = new int[5];//每个线程接收文件的大小 5 public bool hb;//文件合并标志 6 public string[] filenamew = new string[5];//每个线程接收文件的文件名 7 public bool[] threadw = new bool[5]; //每个线程结束标志 8 public int[] threadcount = new int[5] { 0, 0, 0, 0, 0 }; 9 public string StrUrl = "http://www.baidu.com/index.html"; //根据实际情况设置 10 //string StrFileName = ; 11 // public FileStream fs = new FileStream("D:\aa.rmvb", System.IO.FileMode.Create); 12 13 /// <summary> 14 /// 下面代码用于合并5个子文件。 15 /// </summary> 16 public void hbfile() 17 { 18 while (true)//等待 19 { 20 hb = true; 21 for (int i = 0; i < 5; i++) 22 { 23 if (threadw[i] == false)//有未结束线程,等待 24 { 25 hb = false; 26 Thread.Sleep(100); 27 break; 28 } 29 } 30 if (hb == true)//所有线程均已结束,停止等待, 31 { 32 break; 33 } 34 } 35 //FileStream fs;//开始合并 36 if (hb == true) 37 { 38 Console.WriteLine("开始合并"); 39 FileStream fs = new FileStream("D:\temp.html", System.IO.FileMode.Create); 40 FileStream fstemp; 41 int readfile; 42 byte[] bytes = new byte[512]; 43 for (int k = 0; k < 5; k++) 44 { 45 fstemp = new FileStream(filenamew[k], System.IO.FileMode.Open); 46 while (true) 47 { 48 readfile = fstemp.Read(bytes, 0, 512); 49 if (readfile > 0) 50 { 51 fs.Write(bytes, 0, readfile); 52 } 53 else 54 { 55 break; 56 } 57 } 58 fstemp.Close(); 59 } 60 fs.Close(); 61 } 62 63 } 64 /// <summary> 65 /// 接受数据 66 /// </summary> 67 public void receive() 68 { 69 HttpWebRequest request; 70 int filesize = 0; 71 //int filesizeend = 0;//最后一个线程的大小 72 //第一次请求是为了得到文件的大小 73 try 74 { 75 while (true) 76 { 77 request = (HttpWebRequest)HttpWebRequest.Create(StrUrl); 78 filesize = Convert.ToInt32(request.GetResponse().ContentLength); //取得目标文件的长度 79 if (filesize > 0) 80 break; 81 } 82 filesize = filesize / 20; 83 //filesize = filesize / 5;//每个线程1%文件 84 //filesizeend = filesize + (int)filesize % 5;//最后一个块的大小 85 request.Abort();//结束这次请求 86 } 87 catch (Exception er) 88 { 89 Console.WriteLine(er.Message); 90 } 91 92 for (int i = 0; i < 5; i++) 93 { 94 threadw[i] = false;//每个线程状态的初始值为假 95 filenamew[i] = i.ToString() + ".dat";//每个线程接收文件的临时文件名 96 if (i < 4) 97 { 98 filestartw[i] = filesize * i;//每个线程接收文件的起始点 99 filesizew[i] = filesize - 1;//每个线程接收文件的长度 100 } 101 else 102 { 103 filestartw[i] = filesize * i; 104 filesizew[i] = filesize - 1; 105 } 106 } 107 108 //定义线程数组,启动接收线程 109 Thread[] threadk = new Thread[5]; 110 threadbody[] body = new threadbody[5]; 111 for (int j = 0; j < 5; j++) 112 { 113 body[j] = new threadbody(this, j); 114 threadk[j] = new Thread(new ThreadStart(body[j].Download)); 115 threadk[j].Start(); 116 } 117 } 118 119 /// <summary> 120 /// 主方法,开启5个线程下载。 121 /// </summary> 122 /// <param name="args"></param> 123 static void Main(string[] args) 124 { 125 Program p1 = new Program(); 126 p1.receive(); 127 p1.hbfile(); 128 129 } 130 }