public static async Task DownloadFile(string url, string path, bool aria2c, string aria2cProxy, bool forceHttp = false) { if (forceHttp) { url = ReplaceUrl(url); } LogDebug("Start downloading: {0}", url); if (!Directory.Exists(Path.GetDirectoryName(Path.GetFullPath(path)))) { Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path))); } if (aria2c) { await BBDownAria2c.DownloadFileByAria2cAsync(url, path, aria2cProxy); if (File.Exists(path + ".aria2") || !File.Exists(path)) { throw new Exception("aria2下载可能存在错误"); } Console.WriteLine(); return; } int retry = 0; string tmpName = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path) + ".tmp"); reDown: try { using (var progress = new ProgressBar()) { await RangeDownloadToTmpAsync(0, url, tmpName, 0, null, (_, downloaded, total) => progress.Report((double)downloaded / total)); File.Move(tmpName, path, true); } } catch (Exception) { if (++retry == 3) { throw; } goto reDown; } }
public static async Task MultiThreadDownloadFileAsync(string url, string path, bool aria2c, string aria2cProxy, bool forceHttp = false) { if (forceHttp) { url = ReplaceUrl(url); } LogDebug("Start downloading: {0}", url); if (aria2c) { await BBDownAria2c.DownloadFileByAria2cAsync(url, path, aria2cProxy); if (File.Exists(path + ".aria2") || !File.Exists(path)) { throw new Exception("aria2下载可能存在错误"); } Console.WriteLine(); return; } long fileSize = await GetFileSizeAsync(url); LogDebug("文件大小:{0} bytes", fileSize); //已下载过, 跳过下载 if (File.Exists(path) && new FileInfo(path).Length == fileSize) { LogDebug("文件已下载过, 跳过下载"); return; } List <Clip> allClips = GetAllClips(url, fileSize); int total = allClips.Count; LogDebug("分段数量:{0}", total); ConcurrentDictionary <int, long> clipProgress = new(); foreach (var i in allClips) { clipProgress[i.index] = 0; } using (var progress = new ProgressBar()) { progress.Report(0); await Parallel.ForEachAsync(allClips, async (clip, _) => { int retry = 0; string tmp = Path.Combine(Path.GetDirectoryName(path), clip.index.ToString("00000") + "_" + Path.GetFileNameWithoutExtension(path) + (Path.GetExtension(path).EndsWith(".mp4") ? ".vclip" : ".aclip")); reDown: try { await RangeDownloadToTmpAsync(clip.index, url, tmp, clip.from, clip.to == -1 ? null : clip.to, (index, downloaded, _) => { clipProgress[index] = downloaded; progress.Report((double)clipProgress.Values.Sum() / fileSize); }, true); } catch (NotSupportedException) { if (++retry == 3) { throw new Exception($"服务器可能并不支持多线程下载,请使用 --multi-thread false 关闭多线程"); } goto reDown; } catch (Exception) { if (++retry == 3) { throw new Exception($"Failed to download clip {clip.index}"); } goto reDown; } }); } }