个性化阅读
专注于IT技术分析

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

本文概述

你可以从网上下载多种类型的文件:文档, 图片, 视频, 扩展名等。无论你是出于什么原因(应用程序中的更新功能, 获得更多资源等), 都知道如何使用C#下载文件如今必须。

为了完成我们的任务, 我们将依赖于.NET的WebClient类。 WebClient是建立在HttpWebRequest之上的高层抽象, 以简化最常见的任务。

在继续之前, 请不要忘记在类顶部添加必需的use语句, 以便能够使用WebClient下载文件:

using System.Net;

同步地

同步下载文件的最简单方法(将冻结UI), 这要归功于WebClient类, 该类由5行组成:

// A web URL with a file response
string myWebUrlFile = "https://www.google.com/images/icons/ui/doodle_plus/logo.png";
// Local path where the file will be saved
string 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 URL
    string 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.Text
    string 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 = 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");
}

玩得开心

赞(0)
未经允许不得转载:srcmini » 如何使用C#下载Web文件并同步和异步显示下载进度

评论 抢沙发

评论前必须登录!