我有一个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();
}
我试图增加缓冲区大小,但无济于事。如果我添加线程,是否可以提高下载速度?
答案 0 :(得分:0)
根据服务器的不同,您可能会有一些速度下载具有多个细分的文件。
为此你可以使用request.AddRange
并使用不同的线程来下载同一个文件。请注意,将数据写入本地文件时,必须以正确的偏移量开始。
这是大多数下载管理员所做的事情。
请注意,某些服务器不允许这样做。
答案 1 :(得分: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;