public static async Task DownloadFile(string url, string path, bool aria2c) { LogDebug("Start downloading: {0}", url); if (aria2c) { BBDownAria2c.DownloadFileByAria2c(url, path); if (File.Exists(path + ".aria2") || !File.Exists(path)) { throw new Exception("aria2下载可能存在错误"); } Console.WriteLine(); return; } string tmpName = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path) + ".tmp"); using (var progress = new ProgressBar()) { long totalLength = -1; WebClient client = new WebClient(); if (!url.Contains("platform=android_tv_yst")) { client.Headers.Add("Referer", "https://www.bilibili.com"); } client.Headers.Add("User-Agent", "Mozilla/5.0"); client.Headers.Add("Cookie", Program.COOKIE); client.Credentials = CredentialCache.DefaultCredentials; Uri uri = new Uri(url); client.DownloadProgressChanged += delegate(object sender, DownloadProgressChangedEventArgs e) { if (totalLength == -1) { totalLength = e.TotalBytesToReceive; } progress.Report((double)e.BytesReceived / e.TotalBytesToReceive); }; await client.DownloadFileTaskAsync(uri, tmpName); if (new FileInfo(tmpName).Length == totalLength) { File.Move(tmpName, path, true); } else { throw new Exception("文件下载可能不完整, 请重新下载"); } } }
public static async Task MultiThreadDownloadFileAsync(string url, string path, bool aria2c) { if (aria2c) { BBDownAria2c.DownloadFileByAria2c(url, path); if (File.Exists(path + ".aria2") || !File.Exists(path)) { throw new Exception("aria2下载可能存在错误"); } Console.WriteLine(); return; } long fileSize = GetFileSize(url); LogDebug("文件大小:{0} bytes", fileSize); List <Clip> allClips = GetAllClips(url, fileSize); int total = allClips.Count; LogDebug("分段数量:{0}", total); long done = 0; using (var progress = new ProgressBar()) { progress.Report(0); await RunWithMaxDegreeOfConcurrency(8, allClips, async clip => { string tmp = Path.Combine(Path.GetDirectoryName(path), clip.index.ToString("00000") + "_" + Path.GetFileNameWithoutExtension(path) + (Path.GetExtension(path).EndsWith(".mp4") ? ".vclip" : ".aclip")); if (!(File.Exists(tmp) && new FileInfo(tmp).Length == clip.to - clip.from + 1)) { reDown: try { using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0"); client.DefaultRequestHeaders.Add("Cookie", Program.COOKIE); if (clip.to != -1) { client.DefaultRequestHeaders.Add("Range", $"bytes={clip.from}-{clip.to}"); } else { client.DefaultRequestHeaders.Add("Range", $"bytes={clip.from}-"); } if (!url.Contains("platform=android_tv_yst")) { client.DefaultRequestHeaders.Referrer = new Uri("https://www.bilibili.com"); } var response = await client.GetAsync(url); using (var stream = await response.Content.ReadAsStreamAsync()) { using (var fileStream = new FileStream(tmp, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) { var buffer = new byte[8192]; int bytesRead; while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0) { await fileStream.WriteAsync(buffer, 0, bytesRead); done += bytesRead; progress.Report((double)done / fileSize); } //await stream.CopyToAsync(fileStream); } } } } catch { goto reDown; } } else { done += new FileInfo(tmp).Length; progress.Report((double)done / fileSize); } }); } }
public static async Task MultiThreadDownloadFileAsync(string url, string path, bool aria2c) { if (aria2c) { BBDownAria2c.DownloadFileByAria2c(url, path); if (File.Exists(path + ".aria2") || !File.Exists(path)) { throw new Exception("aria2下载可能存在错误"); } Console.WriteLine(); return; } long fileSize = GetFileSize(url); LogDebug("文件大小:{0} bytes", fileSize); List <Clip> allClips = GetAllClips(url, fileSize); int total = allClips.Count; LogDebug("分段数量:{0}", total); long done = 0; using (var progress = new ProgressBar()) { progress.Report(0); await RunWithMaxDegreeOfConcurrency(8, allClips, async clip => { string tmp = Path.Combine(Path.GetDirectoryName(path), clip.index.ToString("00000") + "_" + Path.GetFileNameWithoutExtension(path) + (Path.GetExtension(path).EndsWith(".mp4") ? ".vclip" : ".aclip")); if (!(File.Exists(tmp) && new FileInfo(tmp).Length == clip.to - clip.from + 1)) { reDown: try { using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0"); client.DefaultRequestHeaders.Add("Cookie", Program.COOKIE); if (clip.to != -1) { client.DefaultRequestHeaders.Add("Range", $"bytes={clip.from}-{clip.to}"); } else { client.DefaultRequestHeaders.Add("Range", $"bytes={clip.from}-"); } if (!url.Contains("platform=android_tv_yst")) { client.DefaultRequestHeaders.Referrer = new Uri("https://www.bilibili.com"); } var response = await client.GetAsync(url); using (var stream = await response.Content.ReadAsStreamAsync()) { using (var fileStream = new FileStream(tmp, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) { var buffer = new byte[8192]; int bytesRead; while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0) { await fileStream.WriteAsync(buffer, 0, bytesRead); done += bytesRead; progress.Report((double)done / fileSize); } //await stream.CopyToAsync(fileStream); } } } } catch { goto reDown; } } else { done += new FileInfo(tmp).Length; progress.Report((double)done / fileSize); } }); /*//多线程设置 * ParallelOptions parallelOptions = new ParallelOptions * { * MaxDegreeOfParallelism = 8 * }; * Parallel.ForEach(allClips, parallelOptions, async clip => * { * string tmp = Path.Combine(Path.GetDirectoryName(path), clip.index.ToString("00000") + "_" + Path.GetFileNameWithoutExtension(path) + (Path.GetExtension(path).EndsWith(".mp4") ? ".vclip" : ".aclip")); * if (!(File.Exists(tmp) && new FileInfo(tmp).Length == clip.to - clip.from + 1)) * { * reDown: * try * { *//*HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; * request.Timeout = 30000; * request.ReadWriteTimeout = 30000; //重要 * request.AllowAutoRedirect = true; * request.KeepAlive = false; * request.Method = "GET"; * if (!url.Contains("platform=android_tv_yst")) * request.Referer = "https://www.bilibili.com"; * request.UserAgent = "Mozilla/5.0"; * request.Headers.Add("Cookie", Program.COOKIE); * if (clip.to != -1) * request.AddRange("bytes", clip.from, clip.to); * else * request.AddRange("bytes", clip.from); * using (var response = (HttpWebResponse)request.GetResponse()) * { * using (var responseStream = response.GetResponseStream()) * { * using (var stream = new FileStream(tmp, FileMode.Create, FileAccess.Write, FileShare.Write)) * { * byte[] bArr = new byte[1024]; * int size = responseStream.Read(bArr, 0, (int)bArr.Length); * while (size > 0) * { * stream.Write(bArr, 0, size); * done += size; * progress.Report((double)done / fileSize); * size = responseStream.Read(bArr, 0, (int)bArr.Length); * } * } * } * }*//* * } * catch { goto reDown; } * } * else * { * done += new FileInfo(tmp).Length; * progress.Report((double)done / fileSize); * } * });*/ } }