2017-08-16 395 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

相關問題