打开APP
未登录
开通VIP,畅享免费电子书等14项超值服
开通VIP
首页
好书
留言交流
下载APP
联系客服
C#实现多线程下载文件的方法
牧牧彡
>《C#》
2017.05.16
关注
[csharp]
view plain
copy
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.IO;
using
System.Threading;
using
System.Net;
namespace
WfpApp
{
public
class
MultiDownload
{
#region 变量
private
int
_threadNum;
//线程数量
private
long
_fileSize;
//文件大小
private
string
_fileUrl;
//文件地址
private
string
_fileName;
//文件名
private
string
_savePath;
//保存路径
private
short
_threadCompleteNum;
//线程完成数量
private
bool
_isComplete;
//是否完成
private
volatile
int
_downloadSize;
//当前下载大小(实时的)
private
Thread[] _thread;
//线程数组
private
List<
string
> _tempFiles =
new
List<
string
>();
private
object
locker =
new
object
();
#endregion
#region 属性
/// <summary>
/// 文件名
/// </summary>
public
string
FileName
{
get
{
return
_fileName;
}
set
{
_fileName = value;
}
}
/// <summary>
/// 文件大小
/// </summary>
public
long
FileSize
{
get
{
return
_fileSize;
}
}
/// <summary>
/// 当前下载大小(实时的)
/// </summary>
public
int
DownloadSize
{
get
{
return
_downloadSize;
}
}
/// <summary>
/// 是否完成
/// </summary>
public
bool
IsComplete
{
get
{
return
_isComplete;
}
}
/// <summary>
/// 线程数量
/// </summary>
public
int
ThreadNum
{
get
{
return
_threadNum;
}
}
/// <summary>
/// 保存路径
/// </summary>
public
string
SavePath
{
get
{
return
_savePath;
}
set
{
_savePath = value;
}
}
#endregion
/// <summary>
/// 构造函数
/// </summary>
/// <param name="threahNum">线程数量</param>
/// <param name="fileUrl">文件Url路径</param>
/// <param name="savePath">本地保存路径</param>
public
MultiDownload(
int
threahNum,
string
fileUrl,
string
savePath)
{
this
._threadNum = threahNum;
this
._thread =
new
Thread[threahNum];
this
._fileUrl = fileUrl;
this
._savePath = savePath;
}
public
void
Start()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_fileUrl);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
_fileSize = response.ContentLength;
int
singelNum = (
int
)(_fileSize / _threadNum);
//平均分配
int
remainder = (
int
)(_fileSize % _threadNum);
//获取剩余的
request.Abort();
response.Close();
for
(
int
i = 0; i < _threadNum; i++)
{
List<
int
> range =
new
List<
int
>();
range.Add(i * singelNum);
if
(remainder != 0 && (_threadNum - 1) == i)
//剩余的交给最后一个线程
range.Add(i * singelNum + singelNum + remainder - 1);
else
range.Add(i * singelNum + singelNum - 1);
//下载指定位置的数据
int
[] ran =
new
int
[] { range[0], range[1] };
_thread[i] =
new
Thread(
new
ParameterizedThreadStart(Download));
_thread[i].Name = System.IO.Path.GetFileNameWithoutExtension(_fileUrl) +
"_{0}"
.Replace(
"{0}"
, Convert.ToString(i + 1));
_thread[i].Start(ran);
}
}
private
void
Download(
object
obj)
{
Stream httpFileStream =
null
, localFileStram =
null
;
try
{
int
[] ran = obj
as
int
[];
string
tmpFileBlock = System.IO.Path.GetTempPath() + Thread.CurrentThread.Name +
".tmp"
;
_tempFiles.Add(tmpFileBlock);
HttpWebRequest httprequest = (HttpWebRequest)WebRequest.Create(_fileUrl);
httprequest.AddRange(ran[0], ran[1]);
HttpWebResponse httpresponse = (HttpWebResponse)httprequest.GetResponse();
httpFileStream = httpresponse.GetResponseStream();
localFileStram =
new
FileStream(tmpFileBlock, FileMode.Create);
byte
[] by =
new
byte
[5000];
int
getByteSize = httpFileStream.Read(by, 0, (
int
)by.Length);
//Read方法将返回读入by变量中的总字节数
while
(getByteSize > 0)
{
Thread.Sleep(20);
lock
(locker) _downloadSize += getByteSize;
localFileStram.Write(by, 0, getByteSize);
getByteSize = httpFileStream.Read(by, 0, (
int
)by.Length);
}
lock
(locker) _threadCompleteNum++;
}
catch
(Exception ex)
{
throw
new
Exception(ex.Message.ToString());
}
finally
{
if
(httpFileStream !=
null
) httpFileStream.Dispose();
if
(localFileStram !=
null
) localFileStram.Dispose();
}
if
(_threadCompleteNum == _threadNum)
{
Complete();
_isComplete =
true
;
}
}
/// <summary>
/// 下载完成后合并文件块
/// </summary>
private
void
Complete()
{
Stream mergeFile =
new
FileStream(@_savePath, FileMode.Create);
BinaryWriter AddWriter =
new
BinaryWriter(mergeFile);
foreach
(
string
file
in
_tempFiles)
{
using
(FileStream fs =
new
FileStream(file, FileMode.Open))
{
BinaryReader TempReader =
new
BinaryReader(fs);
AddWriter.Write(TempReader.ReadBytes((
int
)fs.Length));
TempReader.Close();
}
File.Delete(file);
}
AddWriter.Close();
}
}
}
调用方法:
[csharp]
view plain
copy
string
httpUrl = @
"http://172.28.98.96/fdimsservice/2.rar"
;
string
saveUrl = System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop) +
"//"
+ System.IO.Path.GetFileName(httpUrl);
int
threadNumber = 5;
MultiDownload md =
new
MultiDownload(threadNumber, httpUrl, saveUrl);
md.Start();
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报
。
打开APP,阅读全文并永久保存
查看更多类似文章
猜你喜欢
类似文章
【热】
打开小程序,算一算2024你的财运
多线程下载(FtpWebRequest)-程序开发-红黑联盟
图片与字符串的互相转换
在asp.net中使用jQuery实现类似QQ网站的图片切割效果
C# http下载(支持断点续传)
Winform中实现批量文件复制(附代码下载)
c# XML和实体类之间相互转换
更多类似文章 >>
生活服务
热点新闻
留言交流
回顶部
联系我们
分享
收藏
点击这里,查看已保存的文章
导长图
关注
一键复制
下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!
联系客服
微信登录中...
请勿关闭此页面
先别划走!
送你5元优惠券,购买VIP限时立减!
5
元
优惠券
优惠券还有
10:00
过期
马上使用
×