2013-06-03 33 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