【发布时间】:2010-04-26 11:45:11
【问题描述】:
我想使用WebClient(或者还有其他更好的选择?)但是有一个问题。我知道打开流需要一些时间,这是无法避免的。然而,与完全立即阅读相比,阅读它所花费的时间要多得多。
有没有最好的方法来做到这一点?我的意思是两种方式,字符串和归档。 Progress 是我自己的代表,效果很好。
第五次更新:
最后,我成功了。与此同时,我查看了一些解决方案,这些解决方案让我意识到问题出在其他地方。
我已经测试了自定义 WebResponse 和 WebRequest 对象、库 libCURL.NET 甚至 Sockets。
时间上的差异是 gzip 压缩。压缩后的流长度只是正常流长度的一半,因此使用浏览器下载时间不到 3 秒。
如果有人想知道我是如何解决这个问题的,我会放一些代码:(不需要一些标题)
public static string DownloadString(string URL)
{
WebClient client = new WebClient();
client.Headers["User-Agent"] = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.1.249.1045 Safari/532.5";
client.Headers["Accept"] = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
client.Headers["Accept-Encoding"] = "gzip,deflate,sdch";
client.Headers["Accept-Charset"] = "ISO-8859-2,utf-8;q=0.7,*;q=0.3";
Stream inputStream = client.OpenRead(new Uri(URL));
MemoryStream memoryStream = new MemoryStream();
const int size = 32 * 4096;
byte[] buffer = new byte[size];
if (client.ResponseHeaders["Content-Encoding"] == "gzip")
{
inputStream = new GZipStream(inputStream, CompressionMode.Decompress);
}
int count = 0;
do
{
count = inputStream.Read(buffer, 0, size);
if (count > 0)
{
memoryStream.Write(buffer, 0, count);
}
}
while (count > 0);
string result = Encoding.Default.GetString(memoryStream.ToArray());
memoryStream.Close();
inputStream.Close();
return result;
}
我认为异步函数将几乎相同。但我将简单地使用另一个线程来触发此功能。我不需要精确的进度指示。
【问题讨论】:
-
究竟有什么不好?你写入的字符串在哪里?
-
它不好,因为结果是文件末尾只有 2048 (iSize) 个字符。而且下载速度非常慢。
-
您似乎在两个地方读到相同的
Stream;reader和streamRemote...我很困惑...还有;注意:在处理字节时,您并不总是读取整数个字符的块 (iByteSize)。 UI 更新如何在回调中发生也不是很清楚;如果这涉及到会增加延迟的线程切换(被诅咒的DoEvents也是如此)。