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类
}
测试截图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://www.cnblogs.com/s0611163/p/6186315.html
dy("nrwz");