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)
        {
            if (!isCompleted)
            {
                // e.Cancel = true;
                // MessageBox.Show("正在下载,不能关闭");
            }
        }
        #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))
                    {
                        this.Invoke(new InvokeDelegate(() =>
                        {
                            lblMsg.Text = "下载出错,尝试重新开始" + (++tryTimes).ToString();
                        }));
                        HttpDownloadFile(url, filePath);
                        Thread.Sleep(1);
                    }
                }));
            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;

                        #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

                        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;

                        #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

                        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;
                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
            {
                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类
}

时间: 2024-10-20 05:19:45

C#限速下载网络文件的相关文章

Java Http下载网络文件

Java Http下载网络文件 使用URL.BufferedReader读取网络文件,转换为字符串,同时可以保存到本地文件. /** 从网络地址url下载文件读成字符串 * @param downloadUrl 文件的网络地址 * @return */ public static StringBuffer downloadFromUrl(String downloadUrl) { BufferedReader reader = null; StringBuffer stringBuffer =

Java BufferedReader下载网络文件

使用java BufferedReader从网络中读取文件到本地,可以存入数据库,也可以保存到本地 java代码 1.下载网络文件内容转换成StringBuffer /** 从网络地址url下载文件读成字符串 * @param downloadUrl 文件的网络地址 * @return */ public static StringBuffer downloadFromUrl(String downloadUrl) { BufferedReader reader = null; StringBu

网络编程(一):用C#下载网络文件的2种方法

使用C#下载一个Internet上的文件主要是依靠HttpWebRequest/HttpWebResonse和WebClient.具体处理起来还有同步和异步两种方式,所以我们其实有四种组合. 1.使用HttpWebRequest/HttpWebResonse和WebClient HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); WebResponse response = request.GetResponse();

下载网络文件,网络流转换为内存流

string fileext = CSA_BLL.Common.Utils.GetFileExt(filePath); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(filePath); request.Method = "GET"; using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { if (response.

Python下载网络文本数据到本地内存的四种实现方法示例

reference: https://blog.csdn.net/john_bian/article/details/71025372?utm_source=itdadao&utm_medium=referral import urllib.request import requests from io import StringIO import numpy as np import pandas as pd ''' 下载网络文件,并导入CSV文件作为numpy的矩阵 ''' # 网络数据文件

【daily】文件分割限速下载,及合并分割文件

说明 主要功能: 1) 分割文件, 生成下载任务; 2) 定时任务: 检索需要下载的任务, 利用多线程下载并限制下载速度; 3) 定时任务: 检索可合并的文件, 把n个文件合并为完整的文件. GitHub: https://github.com/vergilyn/SpringBootDemo 代码结构: 一.获取远程资源ContentLength.FileName 本来以为很容易, 但如果想较好的得到contentLength.fileName其实很麻烦,主要要看download-url是怎么样

路由器OpenWrt如何脱机(离线)下载BT文件

路由器OpenWrt如何脱机(离线)下载BT文件 1.首先到如下网址下载OpenWrt固件(确保为路由器正确型号). http://downloads.openwrt.org/snapshots/trunk/ar71xx/openwrt-ar71xx-generic-wzr-hp-g450h-squashfs-sysupgrade.bin 2.路由器升级完毕后用telnet输入192.168.1.1(默认地址)连接到路由器,默认没有密码,输入“passwd”修改密码,修改成功后输入“exit”退

解除百度云浏览器端对下载大文件的限制

百度网盘对浏览器端下载大文件做了一些限制,当超过一定大小的文件必须使用百度云管家才可以下载,这给用户的使用带来了不便. [不看分析请直接拉到页底] 1. 百度网盘限速原理 当点击下载一个大文件的时候百度网盘会弹出这样一个提示框. 我们给下个断点,看看是什么代码创建了这个提示框. 然后再次点击下载一个大文件,我们发现断点已经断下来了. 可以看出这里是在把提示对话框显示出来,我们需要查看调用栈往上找找. 跳过一些jQuery的操作,我们看到了这样一个函数,继续往上找. 这个isPlatformWin

实现socket_client下载socket_server文件

Socket模块: 在网络编程中的一个基本组件就是套接字(socket).套接字基本上是两个端点的程序之间的"信息通道".程序分布在不通的计算机上(通过网络连接),通过套接字相互发送信息.在python中的大多数的网络编程都隐藏了socket模块的基本细节,不直接和套接字交互. 套接字包括两个:服务器套接字和客户机套接字.在创建一个服务器套接字后,让它等待连接.这样它就在某个网络地址处(IP:端口)监听,直到有客户端套接字连接.连接完成后,服务器和客户端就可以进行交互了. socket