C#多线程下载大文件
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(); } } }
原文地址:https://blog.csdn.net/qq_35436635/article/details/117680913