C#限速下載網(wǎng)絡(luò)文件的方法實(shí)例
C#限速下載網(wǎng)絡(luò)文件的方法,具體如下:
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> /// 已完成字節(jié)數(shù) /// </summary> private long completedCount = 0; /// <summary> /// 是否完成 /// </summary> private bool isCompleted = true; /// <summary> /// 數(shù)據(jù)塊隊(duì)列 /// </summary> private ConcurrentQueue<MemoryStream> msQueue = new ConcurrentQueue<MemoryStream>(); /// <summary> /// 下載開始位置 /// </summary> private long range = 0; /// <summary> /// 文件大小 /// </summary> private long total = 0; /// <summary> /// 一段時(shí)間內(nèi)的完成節(jié)點(diǎn)數(shù),計(jì)算網(wǎng)速用 /// </summary> private long unitCount = 0; /// <summary> /// 上次計(jì)時(shí)時(shí)間,計(jì)算網(wǎng)速用 /// </summary> private DateTime lastTime = DateTime.MinValue; /// <summary> /// 一段時(shí)間內(nèi)的完成字節(jié)數(shù),控制網(wǎng)速用 /// </summary> private long unitCountForLimit = 0; /// <summary> /// 上次計(jì)時(shí)時(shí)間,控制網(wǎng)速用 /// </summary> private DateTime lastTimeForLimit = DateTime.MinValue; /// <summary> /// 下載文件sleep時(shí)間,控制速度用 /// </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("請(qǐng)求服務(wù)器失敗,重新請(qǐng)求" + tryTimes.ToString() + "次"); this.Invoke(new InvokeDelegate(() => { lblMsg.Text = "請(qǐng)求服務(wù)器失敗,重新請(qǐng)求" + 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 計(jì)算網(wǎng)速/進(jìn)度線程 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 顯示進(jìn)度 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("進(jìn)度:{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 限制網(wǎng)速線程 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; } // 設(shè)置參數(shù) 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; //發(fā)送請(qǐng)求并獲取相應(yīng)回應(yīng)數(shù)據(jù) HttpWebResponse response = request.GetResponse() as HttpWebResponse; if (response.ContentLength == range) { this.Invoke(new InvokeDelegate(() => { lblMsg.Text = "文件已下載"; })); return true; } // 設(shè)置參數(shù) 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); //發(fā)送請(qǐng)求并獲取相應(yīng)回應(yīng)數(shù)據(jù) response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程序才開始向目標(biāo)網(wǎng)頁(yè)發(fā)送Post請(qǐng)求 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 根據(jù)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類 }
測(cè)試截圖:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
上一篇:詳解C#實(shí)現(xiàn)MD5加密的示例代碼
欄 目:C#教程
下一篇:WPF彈出帶蒙板的消息框
本文標(biāo)題:C#限速下載網(wǎng)絡(luò)文件的方法實(shí)例
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/6056.html
您可能感興趣的文章
- 01-10C#實(shí)現(xiàn)多線程下載文件的方法
- 01-10實(shí)現(xiàn)ASP.NET無刷新下載并提示下載完成的開發(fā)思路
- 01-10Silverlight文件上傳下載實(shí)現(xiàn)方法(下載保存)
- 01-10C#實(shí)現(xiàn)附件上傳和下載功能
- 01-10C#異步下載文件
- 01-10基于C#生成條形碼操作知識(shí)匯總附源碼下載
- 01-10基于C#實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲 C#抓取網(wǎng)頁(yè)Html源碼
- 01-10利用C#實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲
- 01-10總結(jié)C#網(wǎng)絡(luò)編程中對(duì)于Cookie的設(shè)定要點(diǎn)
- 01-10使用C#實(shí)現(xiàn)基于TCP和UDP協(xié)議的網(wǎng)絡(luò)通信程序的基本示例


閱讀排行
- 1C語言 while語句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻 器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 04-02jquery與jsp,用jquery
- 01-10delphi制作wav文件的方法
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什