Kam*_*ari 6 c# webclient stream
我想使用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;
}
Run Code Online (Sandbox Code Playgroud)
我认为asyncro功能几乎是一样的.但我将简单地使用另一个线程来激活此功能.我不需要percise进度指示.
由于每次迭代都会覆盖缓冲区,因此您只能从文件中获取最后一个iSize字节,而不会将缓冲区保存在任何地方。以下是有关如何使用 MemoryStream 将文件存储在内存中的示例。
var totalBytes = new MemoryStream(1024 * 1024);
while ((iByteSize = streamRemote.Read(byteBuffer, 0, iByteSize)) > 0)
{
totalBytes.Write(byteBuffer, 0, iByteSize);
iRunningByteTotal += iByteSize;
//Some progress calculation
if (Progress != null) Progress(iProgressPercentage);
}
Run Code Online (Sandbox Code Playgroud)
整个下载完成后,您可以将其转换为文本。
var byteArray = totalBytes.GetBuffer();
var numberOfBytes = totalBytes.Length;
var text = Encoding.Default.GetString(byteArray, 0, numberOfBytes);
Run Code Online (Sandbox Code Playgroud)
更新:该DownloadStringAsync方法基本上与上面相同,但不会给您任何进度指示。还有一些其他异步方法可以触发事件DownloadProgressChanged。
更新2:关于响应时间。您是否使用其他工具定时下载资源?主流浏览器都内置了对此类计时的支持。
此外,它是您提供的静态文件还是在服务器端生成的内容?
我想到的第三件事是服务器端缓冲。例如,如果使用 ASP.Net 中的 Response.Buffer 属性,则在服务器端完成整个文件/页面之前,不会向客户端发送任何内容。因此客户端必须等待才能开始下载。