C#写的异步文件下载器
using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsAppDownloader { public partial class FormDownloader : Form { public FormDownloader() { InitializeComponent(); textBoxDownloadFolder.Text = Directory.GetCurrentDirectory(); if (false) { List<string> list = new List<string>(); list.Add(@"D:\Users\" + Environment.UserName); list.Add(@"C:\Users\" + Environment.UserName); list.Add(@"E:\Users\" + Environment.UserName); list.Add(@"F:\Users\" + Environment.UserName); list.Add(@"G:\Users\" + Environment.UserName); textBoxDownloadFolder.Text = CreateDirectory(list.ToArray(), "feieryun"); } } public static string CreateDirectory(string[] folderPaths, string folderName) { foreach (string folderPath in folderPaths) { try { // 在指定路径下尝试创建一个临时文件夹 string newFolder = Path.Combine(folderPath, folderName); if (Directory.Exists(newFolder)) { return newFolder; } Directory.CreateDirectory(newFolder); return newFolder; } catch (Exception) { // 如果没有创建子文件夹的权限,就继续检查下一个文件夹 } } // 如果所有文件夹都没有创建子文件夹的权限,就返回 null return ""; } public static void ChooseFolder(string SelectedPath, Func<string, Task> callback) { using (FolderBrowserDialog dialog = new FolderBrowserDialog()) { dialog.SelectedPath = SelectedPath; DialogResult result = dialog.ShowDialog(); if (result == DialogResult.OK) { callback(dialog.SelectedPath); } } } private bool isDoingFlag = false; static HttpWebRequest CreateHttp(string url) { HttpWebRequest req = WebRequest.CreateHttp(url); req.UserAgent = "curl/7.76.1"; return req; } async Task<string> getFilenameByURL(string url) { HttpWebRequest request = CreateHttp(url); request.Method = "GET"; WebResponse response = await request.GetResponseAsync(); response.Close(); return getFilenameByHeader(response.Headers); } static string getFilenameByHeader(WebHeaderCollection Headers) { string contentDisposition = Headers["Content-Disposition"]; if (!string.IsNullOrEmpty(contentDisposition)) { int fileNameIndex = contentDisposition.IndexOf("filename=", StringComparison.InvariantCultureIgnoreCase); if (fileNameIndex >= 0) { string fileName = contentDisposition.Substring(fileNameIndex + 9).Trim().TrimStart('"').TrimEnd('"'); return fileName; } } return ""; } public async Task UrlDownloader(string url, string savePath, Func<long, long, Task> callback) { HttpWebRequest request = CreateHttp(url); FileStream output = new FileStream(savePath, FileMode.OpenOrCreate); long downloadPostion = output.Length; long downloadLength = 0; if (downloadPostion > 0) { // 如果这个文件之前下载过,就获取完整的文件大小 HttpWebRequest headReq = CreateHttp(url); headReq.UserAgent = "curl/7.76.1"; headReq.Method = "HEAD"; WebResponse headRes = await headReq.GetResponseAsync(); downloadLength = headRes.ContentLength; headRes.Close(); if (downloadPostion == downloadLength) { // 文件大小相同代表已经下载完成 await callback(downloadPostion, downloadLength); output.Close(); return; } // 请求服务器从当前文件大小的位置开始下载 request.AddRange(downloadPostion); } WebResponse response = await request.GetResponseAsync(); if (downloadPostion == 0) { downloadLength = response.ContentLength; } output.Seek(downloadPostion, SeekOrigin.Begin); using (Stream input = response.GetResponseStream()) { // 指定缓冲区大小 byte[] buffer = new byte[1024 * 1024]; while (isDoingFlag) { int bytesRead = await input.ReadAsync(buffer, 0, buffer.Length); if (bytesRead == 0) { // 读取到0字节代表下载已完成 break; } downloadPostion += bytesRead; await callback(downloadPostion, downloadLength); await output.WriteAsync(buffer, 0, bytesRead); } } output.Close(); response.Close(); } public static string FormatBytes(long bytes) { string[] sizes = { "B", "KB", "MB", "GB", "TB" }; double len = bytes; int order = 0; while (len >= 1024 && order < sizes.Length - 1) { order++; len /= 1024; } return $"{len:0.##} {sizes[order]}"; } private void buttonChooseFolder_Click(object sender, EventArgs e) { ChooseFolder(textBoxDownloadFolder.Text, async (string pathName) => { textBoxDownloadFolder.Text = pathName; }); } private async void buttonStartDownload_Click(object sender, EventArgs e) { buttonStartDownload.Enabled = false; buttonStopDownload.Enabled = true; isDoingFlag = true; string url = textBoxDownloadURL.Text; string filename = await getFilenameByURL(url); Uri uri = new Uri(url); if (string.IsNullOrEmpty(filename)) { filename = uri.Segments[uri.Segments.Length - 1]; } string savePath = Path.Combine(textBoxDownloadFolder.Text, filename); progressBar1.Maximum = 10000; await UrlDownloader(url, savePath, async (long postion, long total) => { long aa = progressBar1.Maximum * postion / total; if (aa > progressBar1.Maximum) { aa = progressBar1.Maximum; } progressBar1.Value = (int)aa; label_progress.Text = "正在下载 " + FormatBytes(postion) + " / " + FormatBytes(total); }); buttonStartDownload.Enabled = true; buttonStopDownload.Enabled = false; } private void buttonStopDownload_Click(object sender, EventArgs e) { buttonStopDownload.Enabled = false; isDoingFlag = false; } } }
标签:异步,return,string,C#,await,url,downloadPostion,using,下载 From: https://www.cnblogs.com/xiangxisheng/p/17396941.html