static void WritePackage(this DownloadComponent self, DownloadComponent.DownloadingTask task) { task.State = DownloadComponent.DownloadingTaskState.Over; byte[] buff = task.HttpRequest.Response.Data; if (buff != null && buff.Length > 0) { self.FileStreamMap[task.Task.Url].Write(buff, 0, buff.Length); } task.HttpRequest.Dispose(); task.HttpRequest = null; Log.Info($"write file Length:{buff.Length}"); if (task.Task.IsLast) { self.FileStreamMap[task.Task.Url].Close(); self.FileStreamMap[task.Task.Url].Dispose(); self.FileStreamMap[task.Task.Url] = null; Log.Info($"Download Over:{task.Task.Url}"); DownloadComponent.DownloadTask checktask = new DownloadComponent.DownloadTask { Url = task.Task.Url, RequestType = DownloadComponent.RequestType.CheckHead, }; self.StandByTasks.AddLast(checktask); } }
/// <summary> /// 开始下载 /// </summary> /// <param name="task"></param> /// <returns></returns> public static DownloadComponent.DownloadingTask StartDownload(this DownloadComponent self, DownloadComponent.DownloadTask task) { DownloadComponent.DownloadingTask res = new DownloadComponent.DownloadingTask(); res.Task = task; res.State = DownloadComponent.DownloadingTaskState.Downloading; if (task.RequestType == DownloadComponent.RequestType.Head || task.RequestType == DownloadComponent.RequestType.CheckHead) { res.HttpRequest = new HTTPRequest(new Uri(task.Url), HTTPMethods.Head, (a, b) => { res.State = DownloadComponent.DownloadingTaskState.DownloadOver; }); res.HttpRequest.Timeout = TimeSpan.FromSeconds(self.timeOut - 1); } else { res.HttpRequest = new HTTPRequest(new Uri(task.Url), (a, b) => { res.State = DownloadComponent.DownloadingTaskState.DownloadOver; }); res.HttpRequest.SetHeader("Range", $"bytes={task.Start}-{task.End}"); res.HttpRequest.Timeout = TimeSpan.FromSeconds(self.timeOut - 1); } res.HttpRequest.Send(); return(res); }
/// <summary> /// 下载完成 /// </summary> /// <param name="task"></param> public static void DownloadOver(this DownloadComponent self, DownloadComponent.DownloadingTask task) { if (task.Task.RequestType == DownloadComponent.RequestType.Head || task.Task.RequestType == DownloadComponent.RequestType.CheckHead) { if (task.HttpRequest.State != HTTPRequestStates.Finished) // 下载失败 { task.HttpRequest.Dispose(); self.ContinuousError++; if (self.ContinuousError >= self.maxTryCount) { throw new Exception("下载连续失败多次"); } var standBy = task.Task; standBy.TryCount++; if (standBy.TryCount >= self.maxTryCount) { throw new Exception("同一个文件下载连续失败多次"); } self.StandByTasks.AddFirst(standBy); return; } self.ContinuousError = 0; long totalBytes = long.Parse(task.HttpRequest.Response.GetFirstHeaderValue("Content-Length")); string modifiedTime = task.HttpRequest.Response.GetFirstHeaderValue("Last-Modified"); #region Check Local File //打开或创建 var fileStream = new FileStream(self.SaveFileMap[task.Task.Url], FileMode.OpenOrCreate, FileAccess.Write); //获取已下载长度 long byteWrites = fileStream.Length; self.DownLoadBytes[task.Task.Url] = byteWrites; self.TotalBytes[task.Task.Url] = totalBytes; //通过本地缓存的服务器文件修改时间和文件总长度检测服务器是否是同一个文件 不是同一个从头开始写入 if (!self.CheckSameFile(task.Task.Url, modifiedTime, totalBytes)) { byteWrites = 0; } Log.Info($"byteWrites: {byteWrites}"); if (byteWrites == totalBytes) { fileStream.Close(); fileStream.Dispose(); self.SuccessCount++; Log.Info("已经下载完成"); return; } else if (task.Task.RequestType == DownloadComponent.RequestType.CheckHead)//下完再检测已经变化了 { fileStream.Close(); fileStream.Dispose(); self.FailureCount++; File.Delete(self.SaveFileMap[task.Task.Url]); Log.Error("下载后检测源文件已变动"); return; } //设置开始写入位置 fileStream.Seek(byteWrites, SeekOrigin.Begin); self.FileStreamMap.Add(task.Task.Url, fileStream); #endregion #region Download File Data int i = 0; while (true) { long start = byteWrites + i * self.packageLength; long end = byteWrites + (i + 1) * self.packageLength - 1; if (end > totalBytes) { end = totalBytes - 1; } DownloadComponent.DownloadTask downloadTask = new DownloadComponent.DownloadTask(); downloadTask.Url = task.Task.Url; downloadTask.Start = start; downloadTask.End = end; downloadTask.RequestType = DownloadComponent.RequestType.Data; downloadTask.Index = i; downloadTask.IsLast = false; self.StandByTasks.AddLast(downloadTask); if (end == totalBytes - 1) { downloadTask.IsLast = true; break; } i++; } #endregion } else { if (task.HttpRequest.State != HTTPRequestStates.Finished) // 下载失败 { task.HttpRequest.Dispose(); self.ContinuousError++; if (self.ContinuousError >= self.maxTryCount) { throw new Exception("下载连续失败多次"); } var standBy = task.Task; standBy.TryCount++; if (standBy.TryCount >= self.maxTryCount) { throw new Exception("同一个文件下载连续失败多次"); } self.StandByTasks.AddFirst(standBy); return; } if (!self.WriteFileTasks.ContainsKey(task.Task.Url)) { self.WriteFileTasks.Add(task.Task.Url, new List <DownloadComponent.DownloadingTask>()); } self.DownLoadBytes[task.Task.Url] += task.Task.End - task.Task.Start; task.State = DownloadComponent.DownloadingTaskState.WaitWrite; self.WriteFileTasks[task.Task.Url].Add(task); self.CheckWriteFile(task.Task.Url); } }