2013-06-03 56 views
2

我有一個C#控制檯應用程序,它從網站下載文件。這裏是我的方法:如何提高網站文件的下載速度?

public bool DownloadFile(string fileUri, string filePath) 
{ 
    using (var response = _GetResponce(fileUri)) { 
     if (response.StatusCode != HttpStatusCode.OK) { 
      return false; 
     } 
     using (var responseStrm = response.GetResponseStream()) { 
      using (var fileStrm = new FileStream(filePath, FileMode.OpenOrCreate)) { 
      var buffer = new byte[CommonConstants.StreamBufferSize]; 
      int bytesRead = responseStrm.Read(buffer, 0, CommonConstants.StreamBufferSize);  
      while(bytesRead > 0) { 
       fileStrm.Write(buffer, 0, bytesRead); 
       bytesRead = responseStrm.Read(buffer, 0, CommonConstants.StreamBufferSize); 
      } 
     } 
    } 
} 

private HttpWebResponse _GetResponce(string requestedUri, string method = "GET") 
{ 
    var request = (HttpWebRequest)WebRequest.Create(requestedUri); 
    request.Method = method; 
    request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13"; 
    request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; 
    request.Headers[HttpRequestHeader.AcceptLanguage] = "ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3"; 
    request.Headers[HttpRequestHeader.AcceptEncoding] = "gzip,deflate"; 
    request.Headers[HttpRequestHeader.AcceptCharset] = "windows-1251,utf-8;q=0.7,*;q=0.7"; 
    return (HttpWebResponse)request.GetResponse(); 
} 

我試圖增加緩衝區大小,無濟於事。如果我添加線程,它可以提高下載速度嗎?

+16

你確定瓶頸是在這個代碼中,而不是在網絡的某個地方? – Rup

+0

是的,我確定。我在幾臺機器上運行這個代碼。 – alexmac

+0

出於好奇,'CommonConstants.StreamBufferSize'的大小是多少?你有沒有想過增加緩衝區大小,也沒有'ReadAllBytes'方法,你也可以嘗試測試/試驗。 – MethodMan

回答

0

根據服務器的不同,您可能會獲得一些速度,下載具有多個段的文件。

對於這個你可以使用request.AddRange和有不同的線程下載相同的文件。請注意,當您將數據寫入本地文件時,您必須以正確的偏移量開始。

這是大多數下載管理者所做的事情。

請注意,有些服務器不允許這樣做。

+0

布魯諾,我試過你的解決方案,它對我有幫助。非常感謝你。 – alexmac

0

在將文件寫入文件之前,您是否嘗試過緩衝更多數據?通常,您希望儘可能快地輪詢套接字 - 這是我的經驗,即使有很多字節可用於讀取,也只能返回相對較小的一部分字節,這意味着套接字吞吐量最終會與開銷掛鉤其餘的循環,這可能是重要的。

試試這個代碼,看看如果你得到一個可衡量的改進:(!)

using (var fileStrm = new FileStream(filePath, FileMode.OpenOrCreate)) 
using (var responseStrm = response.GetResponseStream()) { 
    const int BufferSize = 1 * 1024 * 1024 + CommonConstants.StreamBufferSize; 
    var buffer = new byte[BufferSize]; 
    int offset, bytesRead; 
    do { // Until we've read everything 
     offset = 0; 
     do {  // Until the buffer is very nearly full or there's nothing left to read 
      bytesRead = responseStrm.Read(buffer, offset, BufferSize - offset); 
      offset += bytesRead; 
     } while (bytesRead != 0 && offset + CommonConstants.StreamBufferSize < BufferSize); 

     // Empty the buffer 
     if (offset != 0) { 
      fileStrm.Write(buffer, 0, offset); 
     } 
    } while (bytesRead != 0); 
} 

另外,如果你要接受的gzip和zlib流,你需要打開解壓:

request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; 
+0

不幸的是,增加緩衝區大小並沒有幫助 – alexmac

+0

@Alexander:嗯,值得一試(我已經看到它在過去的工作)。你有沒有嘗試上面的代碼? – Cameron

+0

卡梅隆感謝您的幫助:我試過了您的代碼,根據文件大小,下載速度提高5-10%。這並不壞,但對我來說還不夠。 – alexmac