2017-08-16 114 views
2

我想从URL下载文件,我必须在WebClient和HttpClient之间进行选择。我在网上引用了this文章和其他几篇文章。在任何地方,都建议使用HttpClient,因为它有很好的异步支持和其他.Net 4.5特权。但我仍然不完全相信,需要更多投入。用WebClient或HttpClient下载文件?

我使用下面的代码从Internet下载文件:

Web客户端:

WebClient client = new WebClient(); 
client.DownloadFile(downloadUrl, filePath); 

的HttpClient:

using (HttpClient client = new HttpClient()) 
{   
    using (HttpResponseMessage response = await client.GetAsync(url)) 
    using (Stream streamToReadFrom = await response.Content.ReadAsStreamAsync()) 
    { 
    } 
} 

从我的角度,我能看到的只有一个使用WebClient的缺点是,这将是非异步调用,阻止调用广告。但是如果我不担心线程阻塞或使用client.DownloadFileAsync()来利用异步支持?

另一方面,如果我使用HttpClient,是不是我加载文件的每个单个字节到内存中,然后将其写入本地文件?如果文件大小过大,内存开销是不是很贵?如果我们使用WebClient,可以避免这种情况,因为它会直接写入本地文件而不会占用系统内存。

因此,如果性能是我最重要的,我应该使用哪种方法进行下载?如果我的上述假设是错误的,我想澄清一下,并且我也愿意采用替代方法。

+0

是否https://stackoverflow.com/questions/37799419/download-pdf-file-from-api-using-c-sharp帮助吗? – mjwills

+0

另请参阅https://codereview.stackexchange.com/questions/69950/single-instance-of-reusable-httpclient。 – mjwills

+0

WebClient还有一个问题:它不能在.NET Core中工作。 – CodeOrElse

回答

1

这里有一种方法用它来下载一个URL,并将其保存到一个文件:(我使用Windows 7,因此没有WindowsRT提供给我,所以我还使用System.IO)

public static class WebUtils 
{ 
    private static Lazy<IWebProxy> proxy = new Lazy<IWebProxy>(() => string.IsNullOrEmpty(Settings.Default.WebProxyAddress) ? null : new WebProxy { Address = new Uri(Settings.Default.WebProxyAddress), UseDefaultCredentials = true }); 

    public static IWebProxy Proxy 
    { 
     get { return WebUtils.proxy.Value; } 
    } 

    public static Task DownloadAsync(string requestUri, string filename) 
    { 
     if (requestUri == null) 
      throw new ArgumentNullException(“requestUri”); 

     return DownloadAsync(new Uri(requestUri), filename); 
    } 

    public static async Task DownloadAsync(Uri requestUri, string filename) 
    { 
     if (filename == null) 
      throw new ArgumentNullException(“filename”); 

     if (Proxy != null) 
     { 
      WebRequest.DefaultWebProxy = Proxy; 
     } 

     using (var httpClient = new HttpClient()) 
     { 
      using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri)) 
      { 
       using (
        Stream contentStream = await (await httpClient.SendAsync(request)).Content.ReadAsStreamAsync(), 
        stream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None, Constants.LargeBufferSize, true)) 
       { 
        await contentStream.CopyToAsync(stream); 
       } 
      } 
     } 
    } 
} 

请注意,代码将在工作中使用的代理服务器的地址保存在设置中,如果指定了此设置,则使用该代理服务器。否则,它应该告诉你所有你需要知道的有关使用HttpClient beta下载和保存文件。

按照以下this链接:

+1

https://codereview.stackexchange.com/questions/69950/single-instance-of-reusable-httpclient可能值得一读。 – mjwills

相关问题