当前位置: 移动技术网 > IT编程>开发语言>c# > C#限速下载网络文件的方法实例

C#限速下载网络文件的方法实例

2019年07月18日  | 移动技术网IT编程  | 我要评论

c#限速下载网络文件的方法,具体如下:

using system;
using system.collections.concurrent;
using system.collections.generic;
using system.componentmodel;
using system.data;
using system.drawing;
using system.io;
using system.linq;
using system.net;
using system.text;
using system.text.regularexpressions;
using system.threading;
using system.threading.tasks;
using system.windows.forms;
using common.utils;
using utils;

namespace 爬虫
{
  public partial class form1 : form
  {
    #region 变量
    /// <summary>
    /// 已完成字节数
    /// </summary>
    private long completedcount = 0;
    /// <summary>
    /// 是否完成
    /// </summary>
    private bool iscompleted = true;
    /// <summary>
    /// 数据块队列
    /// </summary>
    private concurrentqueue<memorystream> msqueue = new concurrentqueue<memorystream>();
    /// <summary>
    /// 下载开始位置
    /// </summary>
    private long range = 0;
    /// <summary>
    /// 文件大小
    /// </summary>
    private long total = 0;
    /// <summary>
    /// 一段时间内的完成节点数,计算网速用
    /// </summary>
    private long unitcount = 0;
    /// <summary>
    /// 上次计时时间,计算网速用
    /// </summary>
    private datetime lasttime = datetime.minvalue;
    /// <summary>
    /// 一段时间内的完成字节数,控制网速用
    /// </summary>
    private long unitcountforlimit = 0;
    /// <summary>
    /// 上次计时时间,控制网速用
    /// </summary>
    private datetime lasttimeforlimit = datetime.minvalue;
    /// <summary>
    /// 下载文件sleep时间,控制速度用
    /// </summary>
    private int sleeptime = 1;
    #endregion

    #region form1
    public form1()
    {
      initializecomponent();
    }
    #endregion

    #region form1_load
    private void form1_load(object sender, eventargs e)
    {
      lblmsg.text = string.empty;
      lblbytemsg.text = string.empty;
      lblspeed.text = string.empty;
    }
    #endregion

    #region form1_formclosing
    private void form1_formclosing(object sender, formclosingeventargs e)
    {

    }
    #endregion

    #region btndownload_click 下载
    private void btndownload_click(object sender, eventargs e)
    {
      iscompleted = false;
      btndownload.enabled = false;
      string url = txturl.text.trim();
      string filepath = createfilepath(url);

      #region 下载线程
      thread thread = new thread(new threadstart(() =>
      {
        int trytimes = 0;
        while (!httpdownloadfile(url, filepath))
        {
          thread.sleep(10000);

          trytimes++;
          logutil.log("请求服务器失败,重新请求" + trytimes.tostring() + "次");
          this.invoke(new invokedelegate(() =>
          {
            lblmsg.text = "请求服务器失败,重新请求" + trytimes.tostring() + "次";
          }));
          httpdownloadfile(url, filepath);
        }
      }));
      thread.isbackground = true;
      thread.start();
      #endregion

      #region 保存文件线程
      thread = new thread(new threadstart(() =>
      {
        while (!iscompleted)
        {
          memorystream ms;
          if (msqueue.trydequeue(out ms))
          {
            using (filestream fs = new filestream(filepath, filemode.open, fileaccess.write))
            {
              fs.seek(completedcount, seekorigin.begin);
              fs.write(ms.toarray(), 0, (int)ms.length);
              fs.close();
            }
            completedcount += ms.length;
          }

          if (total != 0 && total == completedcount)
          {
            thread.sleep(100);
            iscompleted = true;
          }

          thread.sleep(1);
        }
      }));
      thread.isbackground = true;
      thread.start();
      #endregion

      #region 计算网速/进度线程
      thread = new thread(new threadstart(() =>
      {
        while (!iscompleted)
        {
          thread.sleep(1000);

          if (lasttime != datetime.minvalue)
          {
            double sec = datetime.now.subtract(lasttime).totalseconds;
            double speed = unitcount / sec / 1024;

            try
            {
              #region 显示速度
              if (speed < 1024)
              {
                this.invoke(new invokedelegate(() =>
                {
                  lblspeed.text = string.format("{0}kb/s", speed.tostring("0.00"));
                }));
              }
              else
              {
                this.invoke(new invokedelegate(() =>
                {
                  lblspeed.text = string.format("{0}mb/s", (speed / 1024).tostring("0.00"));
                }));
              }
              #endregion

              #region 显示进度
              this.invoke(new invokedelegate(() =>
              {
                string strtotal = (total / 1024 / 1024).tostring("0.00") + "mb";
                if (total < 1024 * 1024)
                {
                  strtotal = (total / 1024).tostring("0.00") + "kb";
                }
                string completed = (completedcount / 1024 / 1024).tostring("0.00") + "mb";
                if (completedcount < 1024 * 1024)
                {
                  completed = (completedcount / 1024).tostring("0.00") + "kb";
                }
                lblmsg.text = string.format("进度:{0}/{1}", completed, strtotal);
                lblbytemsg.text = string.format("已下载:{0}\r\n总大小:{1}", completedcount, total);

                if (completedcount == total)
                {
                  messagebox.show("完成");
                }
              }));
              #endregion
            }
            catch { }

            lasttime = datetime.now;
            unitcount = 0;
          }
        }
      }));
      thread.isbackground = true;
      thread.start();
      #endregion

      #region 限制网速线程
      thread = new thread(new threadstart(() =>
      {
        while (!iscompleted)
        {
          thread.sleep(100);

          if (lasttimeforlimit != datetime.minvalue)
          {
            double sec = datetime.now.subtract(lasttimeforlimit).totalseconds;
            double speed = unitcountforlimit / sec / 1024;

            try
            {
              #region 限速/解除限速
              double limitspeed = 0;
              if (double.tryparse(txtspeed.text.trim(), out limitspeed))
              {
                if (speed > limitspeed && sleeptime < 1000)
                {
                  sleeptime += 1;
                }
                if (speed < limitspeed - 10 && sleeptime >= 2)
                {
                  sleeptime -= 1;
                }
              }
              else
              {
                this.invoke(new invokedelegate(() =>
                {
                  txtspeed.text = "100";
                }));
              }
              #endregion
            }
            catch { }

            lasttimeforlimit = datetime.now;
            unitcountforlimit = 0;
          }
        }
      }));
      thread.isbackground = true;
      thread.start();
      #endregion

    }
    #endregion

    #region httpdownloadfile 下载文件
    /// <summary>
    /// http下载文件
    /// </summary>
    public bool httpdownloadfile(string url, string filepath)
    {
      try
      {
        if (!file.exists(filepath))
        {
          using (filestream fs = new filestream(filepath, filemode.create))
          {
            fs.close();
          }
        }
        else
        {
          fileinfo fileinfo = new fileinfo(filepath);
          range = fileinfo.length;
        }

        // 设置参数
        httpwebrequest request = webrequest.create(url) as httpwebrequest;
        request.useragent = "mozilla/4.0 (compatible; msie 8.0; windows nt 6.0; trident/4.0)";
        request.proxy = null;
        //发送请求并获取相应回应数据
        httpwebresponse response = request.getresponse() as httpwebresponse;
        if (response.contentlength == range)
        {
          this.invoke(new invokedelegate(() =>
          {
            lblmsg.text = "文件已下载";
          }));
          return true;
        }

        // 设置参数
        request = webrequest.create(url) as httpwebrequest;
        request.useragent = "mozilla/4.0 (compatible; msie 8.0; windows nt 6.0; trident/4.0)";
        request.proxy = null;
        request.addrange(range);
        //发送请求并获取相应回应数据
        response = request.getresponse() as httpwebresponse;
        //直到request.getresponse()程序才开始向目标网页发送post请求
        stream responsestream = response.getresponsestream();

        total = range + response.contentlength;
        completedcount = range;

        memorystream ms = new memorystream();
        byte[] barr = new byte[1024];
        lasttime = datetime.now;
        lasttimeforlimit = datetime.now;
        int size = responsestream.read(barr, 0, (int)barr.length);
        unitcount += size;
        unitcountforlimit += size;
        ms.write(barr, 0, size);
        while (!iscompleted)
        {
          size = responsestream.read(barr, 0, (int)barr.length);
          unitcount += size;
          unitcountforlimit += size;
          ms.write(barr, 0, size);
          if (ms.length > 102400)
          {
            msqueue.enqueue(ms);
            ms = new memorystream();
          }
          if (completedcount + ms.length == total)
          {
            msqueue.enqueue(ms);
            ms = new memorystream();
          }

          thread.sleep(sleeptime);
        }
        responsestream.close();
        return true;
      }
      catch (exception ex)
      {
        logutil.logerror(ex.message + "\r\n" + ex.stacktrace);
        return false;
      }
    }
    #endregion

    #region 根据url生成文件保存路径
    private string createfilepath(string url)
    {
      string path = application.startuppath + "\\download";
      if (!directory.exists(path))
      {
        directory.createdirectory(path);
      }

      string filename = path.getfilename(url);
      if (filename.indexof("?") > 0)
      {
        return path + "\\" + filename.substring(0, filename.indexof("?"));
      }
      else
      {
        return path + "\\" + filename;
      }
    }
    #endregion

  } //end form1类
}

测试截图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网