/// <summary> /// 下载模组 /// </summary> public void DownloadMod(DownloadStatus status) { DownloadModPrivate(status, 1); }
//内部方法,用于下载失败时递归重试 private void DownloadModPrivate(DownloadStatus status, int tryTime) { //检查下载失败 if (tryTime > TryTime) { DownFailed?.Invoke(this, status); return; } string urlStr = string.Format(BASE_DOWNLOAD_URL, status.ProjectId, status.FileId); //检查网址正确性 if (!Uri.TryCreate(urlStr, UriKind.Absolute, out Uri url)) { throw new FormatException("Url格式错误"); } var req = (HttpWebRequest)WebRequest.Create(url); HttpWebResponse rep; //超时检查 try { rep = (HttpWebResponse)req.GetResponse(); } catch (WebException) { //超时重试 DownloadModPrivate(status, tryTime + 1); return; } //文件总大小 long totalBytes = rep.ContentLength; //已经下载的大小 long downloaded = 0; //缓存 byte[] buffer = new byte[1024]; //当前时间计算反馈周期用 DateTime startTime = DateTime.Now; DateTime endTime; //下载量数组,用于计算速度 Queue <double> insSpeeds = new Queue <double>(20); for (int i = 0; i < 20; i++) { insSpeeds.Enqueue(0.0); } //下载速度 int speed = 0; //获取文件名 string fileName = rep.ResponseUri.Segments.Last(); //获取文件地址 string modPath = Path.Combine(DirectoryPath, "mods", fileName); //临时下载文件地址(下载完成重命名,防止下载中断导致文件损坏) string tmpPath = modPath + ".cfdownload"; //保存参数 status.TotalBytes = totalBytes; status.FileName = fileName; status.Speed = 0; status.DownloadedBytes = 0; //下载开始反馈 status.IsBegin = true; DownBegin?.Invoke(this, status); if (File.Exists(modPath)) { rep.Close(); status.DownloadedBytes = status.TotalBytes; DownComplete?.Invoke(this, status); return; } #region 载具体实现 //创建文件夹 Directory.CreateDirectory(Path.Combine(DirectoryPath, "mods")); //保存流 using (FileStream fsSave = new FileStream(tmpPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { //下载流 using (Stream rsDown = rep.GetResponseStream()) { //单位时间内下载量 int periodBytes = 0; int r = 1; //循环读流 while (r > 0) { //计算速度 endTime = DateTime.Now; TimeSpan span = endTime - startTime; //速度计算周期50ms if (span > TimeSpan.FromMilliseconds(50)) { //瞬时速度 double insSpeed = periodBytes / span.TotalSeconds / 1024; //重置计算 periodBytes = 0; startTime = DateTime.Now; //计算平均速度 insSpeeds.Dequeue(); insSpeeds.Enqueue(insSpeed); speed = (int)insSpeeds.Average(); } //反馈进度 status.DownloadedBytes = downloaded; status.Speed = speed; try { r = rsDown.Read(buffer, 0, 1024); //读流 fsSave.Write(buffer, 0, r); //存流 } catch (IOException) { fsSave.Close(); rsDown.Close(); DownloadModPrivate(status, tryTime + 1); return; } //保存进度 downloaded += r; periodBytes += r; } } } //下载完成,重命名文件(防止下载中断错误) if (File.Exists(modPath)) { File.Delete(modPath); } File.Move(tmpPath, modPath); //下载完成反馈 Thread.Sleep(100); DownComplete?.Invoke(this, status); #endregion }
public void Begin(DownloadStatus status) { txtName.Text = status.FileName; }