public static async void Start(DownloadInfo info, IDownloadManagerListener managerListener) { try { var file = await GetFileSize(info); info.FileSize = file.Item2; if (string.IsNullOrEmpty(info.Name)) { info.Name = file.Item1; } info.Listener.OnDownloadStart(info); if (info.FileSize > _multiThreadMinSize) { Task.Run(() => DownloadWithMultiThreed(info, managerListener)); } else if (info.FileSize > 0) { Task.Run(() => DownloadWithSingleThreed(info, managerListener)); } else { DownloadUnKownSizeFile(info, managerListener); } } catch (Exception ex) { Logger.LogHelper.Error("下载文件出错", ex); info.Exception = ex; info.Message = ex.Message; info.Listener.OnDownloadFailed(info); } }
private static async void DownloadUnKownSizeFile(DownloadInfo info, IDownloadManagerListener managerListener) { try { using (var httpClient = CreateHttpClient()) { var response = await httpClient.GetAsync(info.Url, HttpCompletionOption.ResponseHeadersRead, info.CancellationTokenSource.Token); using (var stream = await response.Content.ReadAsStreamAsync()) { var bytes = new byte[_bytesLength]; using ( var fileStream = new FileStream(Path.Combine(info.Url, info.Name), FileMode.Append, FileAccess.Write)) { int writeLength; stream.Position = fileStream.Length; while ((writeLength = (stream.Read(bytes, 0, _bytesLength))) > 0) { if (info.CancellationTokenSource.Token.IsCancellationRequested) { info.DownloadStatus = DownloadStatus.UnDownload; info.Listener.OnDownloadCancled(info); break; } fileStream.Write(bytes, 0, writeLength); info.DownloadSize += writeLength; info.Listener.OnDownloadProgress(info); } fileStream.Flush(); fileStream.Close(); stream.Flush(); stream.Close(); } if (info.DownloadStatus == DownloadStatus.Downloading) { info.DownloadStatus = DownloadStatus.Downloaded; info.Listener.OnDownloadCompleted(info); managerListener.OnDownloadCompleted(info); } } } } catch (Exception ex) { Logger.LogHelper.Error("下载文件出错", ex); info.Exception = ex; info.Message = ex.Message; info.DownloadStatus = DownloadStatus.DownloadFailed; info.Listener.OnDownloadFailed(info); } }
/// <summary> /// 单线程下载 /// </summary> /// <param name="info"></param> /// <param name="managerListener"></param> public static async void DownloadWithSingleThreed(DownloadInfo info, IDownloadManagerListener managerListener) { try { var contentLength = info.FileSize; if (info.FileSize <= 0 || string.IsNullOrEmpty(info.Name)) { var file = await GetFileSize(info); if (string.IsNullOrEmpty(info.Name)) { info.Name = file.Item1; } if (file.Item2 <= 0) { DownloadUnKownSizeFile(info, managerListener); return; } } if (string.IsNullOrEmpty(info.Name)) { info.Name = Guid.NewGuid().ToString(); } info.Listener.OnDownloadStart(info); using (var httpClient = CreateHttpClient()) { if (!Directory.Exists(info.SavePath)) { Directory.CreateDirectory(info.SavePath); } using (var fileStream = new FileStream(Path.Combine(info.SavePath, info.Name), FileMode.Append, FileAccess.Write)) { var bytes = new byte[_bytesLength]; var beginSecond = DateTime.Now.Second; if (fileStream.Length >= contentLength) { info.Listener.OnDownloadCompleted(info); managerListener.OnDownloadCompleted(info); return; } httpClient.DefaultRequestHeaders.Add("Range", "bytes = " + fileStream.Length + " - " + (contentLength - 1)); contentLength -= fileStream.Length; var response = await httpClient.GetAsync(info.Url, info.CancellationTokenSource.Token); using (var stream = await response.Content.ReadAsStreamAsync()) { int writeLength; var readLength = _bytesLength; if (readLength != -1 && contentLength < readLength) { readLength = (int)contentLength; } while ((writeLength = (stream.Read(bytes, 0, readLength))) > 0) { if (info.CancellationTokenSource.Token.IsCancellationRequested) { info.Listener.OnDownloadCancled(info); } fileStream.Write(bytes, 0, writeLength); info.DownloadSize += writeLength; info.Progress = info.DownloadSize / contentLength; if (beginSecond != DateTime.Now.Second) { info.Speed = writeLength / (DateTime.Now.Second - beginSecond) / 1024; } info.Listener.OnDownloadProgress(info); contentLength -= writeLength; if (contentLength <= 0) { info.DownloadStatus = DownloadStatus.Downloaded; info.Listener.OnDownloadCompleted(info); managerListener.OnDownloadCompleted(info); } } stream.Flush(); stream.Close(); } fileStream.Flush(); fileStream.Close(); } } } catch (Exception ex) { Logger.LogHelper.Error("下载文件出错", ex); info.Message = ex.Message; info.Exception = ex; info.DownloadStatus = DownloadStatus.DownloadFailed; info.Listener.OnDownloadFailed(info); managerListener.OnDownloadFailed(info); } }
public static async void DownloadWithMultiThreed(DownloadInfo info, IDownloadManagerListener managerListener) { try { var contentLength = info.FileSize; if (info.FileSize <= 0 || string.IsNullOrEmpty(info.Name)) { var file = await GetFileSize(info); if (string.IsNullOrEmpty(info.Name)) { info.Name = file.Item1; } if (file.Item2 <= 0) { DownloadUnKownSizeFile(info, managerListener); return; } } if (string.IsNullOrEmpty(info.Name)) { info.Name = Guid.NewGuid().ToString(); } info.Listener.OnDownloadStart(info); var fileInfo = new FileInfo { FileLength = contentLength }; if (_downloadingFiles.ContainsKey(info.Url)) { _downloadingFiles.Remove(info.Url); } _downloadingFiles.Add(info.Url, fileInfo); int taskCount = (int)(_downloadingFiles[info.Url].FileLength / _oneThreadSize); var tasks = new List <Task>(); for (int i = 0; i < _maxThread; i++) { if (taskCount <= 0) { break; } taskCount--; var t = Task.Run(async() => { await DownloadChunk(info); }); tasks.Add(t); } Task.WaitAll(tasks.ToArray()); if (info.DownloadStatus == DownloadStatus.Downloading) { MergeFile(info); info.DownloadStatus = DownloadStatus.Downloaded; info.Listener.OnDownloadCompleted(info); managerListener.OnDownloadCompleted(info); } } catch (Exception ex) { Logger.LogHelper.Error("下载文件出错", ex); if (info.Message == null) { info.Exception = ex; info.Message = ex.Message; } info.DownloadStatus = DownloadStatus.DownloadFailed; info.Listener.OnDownloadFailed(info); managerListener.OnDownloadFailed(info); } }