using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SingleDownloader
{
class DownloadingInformation
{
public int blocks { get; set; }
public int finished { set; get; }
public DownloadingInformation(int blocks,int finished)
{
this.blocks = blocks;
this.finished = finished;
}
}
class PartialInformation
{
public string url { get; set; }
public long start { get; set; }
public long end { set; get; }
public PartialInformation(string url,long start,long end)
{
this.url = url;
this.start = start;
this.end = end;
}
}
class DownloadInformation
{
public string link { get; set; }
public string storeDir { get; set; }
public string fileName { get; set; }
public DownloadInformation(string link, string dir)
{
this.link = link;
this.storeDir = dir;
this.fileName = link.Split('/').Last<string>();
}
public DownloadInformation(string link, string dir, string fileName)
{
this.link = link;
this.storeDir = dir;
this.fileName = fileName;
}
public override string ToString()
{
return string.Format("link:{0} storeDir:{1} fileName:{2}", link, storeDir, fileName);
}
}
class Program
{
//下载信息
private static DownloadInformation downloadInformation;
//下载过程中的信息,包括进度等
private static DownloadingInformation downloadingInformation;
//多线程锁
private static ManualResetEvent manualResetEvent;
private static long getSize(string url)
{
HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
httpWebRequest.AddRange(0, 1);
HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();
string contentRange=response.Headers.Get("Content-Range");
long res = long.Parse(contentRange.Split('/').Last<string>());
response.Close();
return res;
}
private static void partialDownload(Object param)
{
PartialInformation info = param as PartialInformation;
HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(info.url);
httpWebRequest.AddRange(info.start, info.end);
HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();
var stream=response.GetResponseStream();
FileStream fstream = new FileStream(downloadInformation.storeDir+"/"+downloadInformation.fileName, FileMode.Open,FileAccess.Write,FileShare.Write);
fstream.Seek(info.start,SeekOrigin.Begin);
byte[] content = new byte[1024];
int len = 0;
while((len= stream.Read(content, 0, 1024)) > 0)
{
fstream.Write(content, 0, len);
}
stream.Close();
fstream.Close();
response.Close();
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write("已下载:{0}/{1}MB",++downloadingInformation.finished, downloadingInformation.blocks);
if (downloadingInformation.finished == downloadingInformation.blocks)
//通知主线程结束
manualResetEvent.Set();
}
static void Main(string[] args)
{
downloadInformation = new DownloadInformation(args[0], args[1], args[2]);
long size = getSize(downloadInformation.link);
Console.WriteLine("总大小:{0}字节",size);
ThreadPool.SetMinThreads(10, 10);
ThreadPool.SetMaxThreads(20, 20);
FileStream file = File.Create(downloadInformation.storeDir + "/" + downloadInformation.fileName);
file.Close();
downloadingInformation=new DownloadingInformation((int)Math.Ceiling(size / 1048576.0),0);
for (long i = 0; i < downloadingInformation.blocks; i++)
{
var ii = new PartialInformation(downloadInformation.link, 1048576 * i, 1048576 * (i + 1) - 1);
ThreadPool.QueueUserWorkItem(partialDownload, ii);
}
manualResetEvent = new ManualResetEvent(false);
//阻塞主线程,等待所有子线程完成
manualResetEvent.WaitOne();
}
}
}
接收3个参数,第一个是下载链接,第二个是存储文件夹,第三个是文件名称