/// <summary> /// 保存文件下载的配置信息,包括总字节数、已下载字节数、下载队列信息 /// </summary> /// <param name="configFile"></param> /// <param name="downloadSize"></param> /// <param name="totalSize"></param> /// <param name="downloadQueue"></param> public static void SaveConfig(string configFile, long downloadSize, long totalSize, Queue <ThreadDownloadInfo> downloadQueue) { var config = new FileDownloadConfig() { DownloadSize = downloadSize, TotalSize = totalSize, DownloadQueue = downloadQueue }; Utils.WriteObjectToDisk(configFile, config); }
public async void StartDownload(FileDownloadInfo info) { if (string.IsNullOrEmpty(info.DownLoadUrl)) { throw new Exception("下载地址不能为空!"); } if (!info.DownLoadUrl.ToLower().StartsWith("http://") || !info.DownLoadUrl.ToLower().StartsWith("https://")) { throw new Exception("非法的下载地址!"); } downloadSize = 0; await Task.Run(() => { try { long totalSize = 0; long threadInitedLength = 0; //分配线程任务的下载量 #region 获取文件信息 //打开网络连接 HttpWebRequest initRequest = (HttpWebRequest)WebRequest.Create(info.DownLoadUrl); WebResponse initResponse = initRequest.GetResponse(); FileInfo fileMsg = FileInfo.GetFileMessage(initResponse); totalSize = fileMsg.Length; if ((!string.IsNullOrEmpty(fileMsg.FileName)) && info.LocalSaveFolder != null) { info.SavePath = Path.Combine(info.LocalSaveFolder, fileMsg.FileName); } //ReaderWriterLock readWriteLock = new ReaderWriterLock(); #endregion #region 读取配置文件 string configPath = info.SavePath.Substring(0, info.SavePath.LastIndexOf(".")) + ".cfg"; FileDownloadConfig initInfo = null; if (File.Exists(configPath) && (info.IsNew == false)) { initInfo = FileDownloadConfig.ReadConfig(configPath); downloadSize = (long)initInfo.DownloadSize; totalSize = (long)initInfo.TotalSize; } #endregion #region 计算速度 //Stopwatch MyStopWatch = new Stopwatch(); long lastDownloadSize = 0; //上次下载量 bool isSendCompleteEvent = false; //是否完成 Timer timer = new Timer(new TimerCallback((o) => { if (!isSendCompleteEvent) { FileDownloadEvent e = new FileDownloadEvent(); e.DownloadSize = downloadSize; e.TotalSize = totalSize; if (totalSize > 0 && downloadSize == totalSize) { e.Speed = 0; isSendCompleteEvent = true; eventFinished.Set(); } else { e.Speed = downloadSize - lastDownloadSize; lastDownloadSize = downloadSize; //更新上次下载量 } DownloadEvent(e); } }), null, 0, 1000); #endregion string tempPath = info.SavePath.Substring(0, info.SavePath.LastIndexOf(".")) + ".dat"; #region 多线程下载 //分配下载队列 Queue <ThreadDownloadInfo> downQueue = null; if (initInfo == null || info.IsNew) { downQueue = new Queue <ThreadDownloadInfo>(); //下载信息队列 while (threadInitedLength < totalSize) { ThreadDownloadInfo downInfo = new ThreadDownloadInfo(); downInfo.StartLength = threadInitedLength; downInfo.Length = (int)Math.Min(Math.Min(THREAD_BUFFER_SIZE, totalSize - threadInitedLength), totalSize / info.ThreadCount); //下载量 downQueue.Enqueue(downInfo); threadInitedLength += downInfo.Length; } } else { downQueue = initInfo.DownloadQueue; } FileStream fs = new FileStream(tempPath, FileMode.OpenOrCreate); fs.SetLength(totalSize); int threads = info.ThreadCount; for (int i = 0; i < info.ThreadCount; i++) { ThreadPool.QueueUserWorkItem((state) => { ThreadWork(info.DownLoadUrl, fs, downQueue); if (Interlocked.Decrement(ref threads) == 0) { (state as AutoResetEvent).Set(); } }, eventFinished); } //等待所有线程完成 eventFinished.WaitOne(); if (fs != null) { fs.Close(); } fs = null; if (File.Exists(info.SavePath)) { File.Delete(info.SavePath); } if (downloadSize == totalSize) { File.Move(tempPath, info.SavePath); File.Delete(configPath); } if (cancelTokenSource.IsCancellationRequested && StopEvent != null) { StopEvent(); //保存配置文件 FileDownloadConfig.SaveConfig(configPath, downloadSize, totalSize, downQueue); } #endregion } catch (Exception ex) { ErrorMakedEvent?.Invoke(ex.Message); } }); }