• 实现多线程下载文件


    引用命名空间:

    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     }
    View Code

    下载类:

      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     }
    View Code
  • 相关阅读:
    2014年工作总结
    正则表达式语法规则
    按照事务类型分析 DB2 事物的性能
    DB2定位锁等待
    深入研究线程池
    WebSphere应用服务器内存泄漏探测与诊断工具选择最佳实践
    一次WebSphere性能问题诊断过程
    WebSphere Application Server诊断和调优
    将 Spring 和 Hibernate 与 WebSphere Application Server 一起使用
    Websphere Application Server 环境配置与应用部署最佳实践
  • 原文地址:https://www.cnblogs.com/ziranquliu/p/4749082.html
Copyright © 2020-2023  润新知