C#限速下载网络文件的方法实例
程序员文章站
2022-07-06 10:59:06
c#限速下载网络文件的方法,具体如下:
using system;
using system.collections.concurrent;
using...
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类 }
测试截图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 浅谈C# 类的继承
下一篇: C# Socket的TCP通讯的实例代码