定义一个HttpFile类,用于管理接收线程,其代码如下:
| public class HttpFile { public Form1 formm; public int threadh;//线程代号 public string filename;//文件名 public string strUrl;//接收文件的URL public FileStream fs; public HttpWebRequest request; public System.IO.Stream ns; public byte[] nbytes;//接收缓冲区 public int nreadsize;//接收字节数 public HttpFile(Form1 form,int thread)//构造方法 { formm=form; threadh=thread; } ~HttpFile()//析构方法 { formm.Dispose (); } public void receive()//接收线程 { filename=formm.filenamew[threadh]; strUrl=formm.strurl; ns=null; nbytes= new byte[512]; nreadsize=0; formm.listBox1 .Items .Add ("线程"+threadh.ToString ()+"开始接收"); fs=new FileStream (filename,System.IO.FileMode.Create); try { request=(HttpWebRequest)HttpWebRequest.Create (strUrl); //接收的起始位置及接收的长度 request.AddRange(formm.filestartw [threadh], formm.filestartw [threadh]+formm.filesizew [threadh]); ns=request.GetResponse ().GetResponseStream ();//获得接收流 nreadsize=ns.Read (nbytes,0,512); while (nreadsize>0) { fs.Write (nbytes,0,nreadsize); nreadsize=ns.Read (nbytes,0,512); formm.listBox1 .Items .Add ("线程"+threadh.ToString ()+"正在接收"); } fs.Close(); ns.Close (); } catch (Exception er) { MessageBox.Show (er.Message ); fs.Close(); } formm.listBox1 .Items.Add ("进程"+threadh.ToString ()+"接收完毕!"); formm.threadw[threadh]=true; } } |
该类和Form1类处于统一命名空间,但不包含在Form1类中。下面定义“开始接收”按钮控件的事件响应函数:
| private void button1_Click(object sender, System.EventArgs e) { DateTime dt=DateTime.Now;//开始接收时间 textBox1.Text =dt.ToString (); strurl=textBox2.Text .Trim ().ToString (); HttpWebRequest request; long filesize=0; try { request=(HttpWebRequest)HttpWebRequest.Create (strurl); filesize=request.GetResponse ().ContentLength;//取得目标文件的长度 request.Abort (); } catch (Exception er) { MessageBox.Show (er.Message ); } // 接收线程数 thread=Convert.ToInt32 (textBox4.Text .Trim().ToString (),10); //根据线程数初始化数组 threadw=new bool [thread]; filenamew=new string [thread]; filestartw=new int [thread]; filesizew=new int[thread]; //计算每个线程应该接收文件的大小 int filethread=(int)filesize/thread;//平均分配 int filethreade=filethread+(int)filesize%thread;//剩余部分由最后一个线程完成 //为数组赋值 for (int i=0;i<thread;i++) { threadw[i]=false;//每个线程状态的初始值为假 filenamew[i]=i.ToString ()+".dat";//每个线程接收文件的临时文件名 if (i<thread-1) { filestartw[i]=filethread*i;//每个线程接收文件的起始点 filesizew[i]=filethread-1;//每个线程接收文件的长度 } else { filestartw[i]=filethread*i; filesizew[i]=filethreade-1; } } //定义线程数组,启动接收线程 Thread[] threadk=new Thread [thread]; HttpFile[] httpfile=new HttpFile [thread]; for (int j=0;j<thread;j++) { httpfile[j]=new HttpFile(this,j); threadk[j]=new Thread(new ThreadStart (httpfile[j].receive )); threadk[j].Start (); } //启动合并各线程接收的文件线程 Thread hbth=new Thread (new ThreadStart (hbfile)); hbth.Start (); } |
合并文件的线程hbfile定义在Form1类中,定义如下:
| public void hbfile() { while (true)//等待 { hb=true; for (int i=0;i<thread;i++) { if (threadw[i]==false)//有未结束线程,等待 { hb=false; Thread.Sleep (100); break; } } if (hb==true)//所有线程均已结束,停止等待, { break; } } FileStream fs;//开始合并 FileStream fstemp; int readfile; byte[] bytes=new byte[512]; fs=new FileStream (textBox3.Text .Trim ().ToString (),System.IO.FileMode.Create); for (int k=0;k<thread;k++) { fstemp=new FileStream (filenamew[k],System.IO.FileMode .Open); while (true) { readfile=fstemp.Read (bytes,0,512); if (readfile>0) { fs.Write (bytes,0,readfile); } else { break; } } fstemp.Close (); } fs.Close (); DateTime dt=DateTime.Now; textBox1.Text =dt.ToString ();//结束时间 MessageBox.Show ("接收完毕!!!"); } |
至此,一个多线程下载文件的程序就大功告成了,注意在输入本地文件名时,应按如下格式输入:“c:\\test\\httpftp\\bin\\d.htm”,因”\”后的字符在C#中是转义字符,线程数并非越大越好,一般5个线程就可以了,该程序在Visual Studio.Net 2002开发环境及Windows xp 操作系统上通过。Web: http://www.qqread.com/csharp/d536131002.html
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
相关专题
- TCP/IP协议 (1919篇文章)
- SIP协议---NGN网络的核心协议 (2109篇文章)
- 协议大全 (1720篇文章)
- HTTP协议 (335篇文章)
- Windows Shell开发:浏览一个文件夹 (0次浏览)
- Windows Shell编程系列 - 获取图标 (0次浏览)
- Windows Shell 开发:从“桌面”开始展开 (0次浏览)
- 实验分析C#中三种计时器使用异同点 (0次浏览)
- C#调用QTP自动化对象模型的实例 (0次浏览)
- 利用 C# 实现任务栏通知窗口 (0次浏览)
- 深入C#学习系列之不可小瞧的using关键字 (0次浏览)
- 如何用.NET技术在线生成网站LOGO (0次浏览)
- C#实现遗传算法 模拟花朵的进化 (0次浏览)
- c#里的运算符重载 (0次浏览)



