如何使用C#下载Web文件并同步和异步显示下载进度

本文概述

  • 同步地
  • 异步地
  • 取消异步下载
  • 总结
你可以从网上下载多种类型的文件:文档, 图片, 视频, 扩展名等。无论你是出于什么原因(应用程序中的更新功能, 获得更多资源等), 都知道如何使用C#下载文件如今必须。
为了完成我们的任务, 我们将依赖于.NET的WebClient类。 WebClient是建立在HttpWebRequest之上的高层抽象, 以简化最常见的任务。
在继续之前, 请不要忘记在类顶部添加必需的use语句, 以便能够使用WebClient下载文件:
using System.Net;

同步地【如何使用C#下载Web文件并同步和异步显示下载进度】同步下载文件的最简单方法(将冻结UI), 这要归功于WebClient类, 该类由5行组成:
// A web URL with a file responsestring myWebUrlFile = "https://www.google.com/images/icons/ui/doodle_plus/logo.png"; // Local path where the file will be savedstring myLocalFilePath = "C:/users/desktop/logo.png"; using (var client = new WebClient()){client.DownloadFile(myWebUrlFile, myLocalFilePath); }

在前面的示例中, 你应该了解DownloadFile方法的工作方式。但是, 取决于你如何实现和完善该方法。
请注意, 在我们的示例中, 由于WebClient实现IDisposable是一种很好的做法, 因此我们使用了using语句。
以下代码片段将以其原始名称(使用getFilename方法从url检索)在桌面上下载文件:
/// < summary> /// Download a file in the desktop path and save it with the original filename./// < /summary> private void downloadFile(){string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); // Change the url by the value you want (a textbox or something else)string url = "https://www.google.com/images/icons/ui/doodle_plus/logo.png"; // Get filename from URLstring filename = getFilename(url); using (var client = new WebClient()){client.DownloadFile(url, desktopPath + "/" + filename); }MessageBox.Show("Download ready"); }/// < summary> /// Get the filename from a web url : /// /// www.google.com/image.png -> returns : image.png/// /// < /summary> /// < param name="hreflink"> < /param> /// < returns> < /returns> private string getFilename(string hreflink){Uri uri = new Uri(hreflink); string filename = System.IO.Path.GetFileName(uri.LocalPath); return filename; }

要测试代码段, 只需执行以下操作即可执行downloadFile方法:单击按钮。
异步地通常, 通常并且显然我们不希望冻结UI, 并且你应该始终选择异步方式(除非你遇到例外情况)。
在这种情况下, 我们将使用WebClient.DownloadFileAsync方法
/// < summary> /// Download a file asynchronously in the desktop path, show the download progress and save it with the original filename./// < /summary> private void downloadFile(){string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); // This will download a large image from the web, you can change the value// i.e a textbox : textBox1.Textstring url ="http://feelgrafix.com/data/wallpaper-hd/Wallpaper-HD-11.jpg"string filename = getFilename(url); using (WebClient wc = new WebClient()){wc.DownloadProgressChanged += wc_DownloadProgressChanged; wc.DownloadFileCompleted += wc_DownloadFileCompleted; wc.DownloadFileAsync(new Uri(url), desktopPath + "/" + filename); }}/// < summary> ///Show the progress of the download in a progressbar/// < /summary> /// < param name="sender"> < /param> /// < param name="e"> < /param> private void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e){// In case you don't have a progressBar Log the value instead // Console.WriteLine(e.ProgressPercentage); progressBar1.Value = http://www.srcmini.com/e.ProgressPercentage; }private void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e){progressBar1.Value = 0; if (e.Cancelled){MessageBox.Show("The download has been cancelled"); return; }if (e.Error != null) // We have an error! Retry a few times, then abort.{MessageBox.Show("An error ocurred while trying to download file"); return; }MessageBox.Show("File succesfully downloaded"); }

由于该方法是异步的, 因此我们需要在downloadFile方法中正确实例化回调。
要测试代码段, 请在表单中添加进度条, 并通过一些操作(即单击按钮)执行downloadFile方法。
另外, 你可以在DownloadProgressChanged事件中显示文件的文件大小(以字节为单位)中待处理的字节总数:
private void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e){Console.WriteLine(e.ProgressPercentage + "% | " + e.BytesReceived + " bytes out of " + e.TotalBytesToReceive + " bytes retrieven."); // 50% | 5000 bytes out of 10000 bytes retrieven.}

取消异步下载取消下载的可能性是文件下载生命周期中的重要基础。
要取消WebClient下载, 你只需要使用创建的Web客户端的CancelAsync方法。
WebClient client = new WebClient(); private void downloadFile(){string url = "https://www.google.com/images/icons/ui/doodle_plus/logo.png"; string myLocalFilePath = "C:/users/desktop/logo.png"; using (client){client.DownloadFileAsync(new Uri(url), myLocalFilePath); }}private void cancelDownload(){client.CancelAsync(); }

注意:由于在类中而不是在downloadFile方法中附加侦听器更为容易, 因此我们可以从cancelDownload和downloadFile方法访问全局范围内的客户端。要测试代码段, 只需将方法添加为一对按钮的操作即可。
请记住, 要检查文件下载是否已取消, 请添加DownloadFileCompleted回调并验证event.Cancelled值, 如异步示例中所示。
总结如果允许并且可以从服务器访问文件, 则与协议(http或https)无关, 下载文件时不会出现任何问题(只要有Internet)。
你可以使用一些技巧来防止创建空文件, 以防无法使用NetworkInterface的GetIsNetworkAvailable来访问互联网:
if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()){MessageBox.Show("Internet available, proceed with the download"); }

玩得开心

    推荐阅读