我使用Response.Filter是为了根据HTTP请求头Accept-Encoding实现流压缩
这里有一些重要的东西:
if (AcceptEncoding.Contains("deflate") || AcceptEncoding == "*")
{
HttpApp.Response.Filter = new DeflateStream(PreviousOutputStream, CompressionMode.Compress);
HttpApp.Response.AppendHeader("Content-Encoding", "deflate");
}大体上,这是预期的工作。但是,我遇到了这样一种情况:我在MVC控制器上使用ActionResult向用户代理提供文件:
Response.Clear();
Response.Headers["Content-Type"] = contentType;
Response.Headers["Content-Length"] = contentLength;
if (Request.QueryString["dl"] == "1")
{
Response.Headers["Content-Disposition"] = "attachment; filename=" + fileInfo.Name;
}
Response.Flush();
Response.TransmitFile(fileInfo.FullName);更准确地说,动作方法在Response.TransmitFile()调用之后返回new EmptyResult()。这在没有Response.Filter修改的情况下完全按照预期工作。
在这种情况下,响应实体到达用户代理时会变得混乱和难以理解。FireFox的海报插件显示了返回的空实体或杂乱的实体。
发布于 2010-11-05 09:11:31
如果你可以帮助它,一定要寻找替代方案,因为在ASP.NET中手动进行压缩并不有趣。但是,如果你像我一样头脑冷静,我向你提出以下几点。
首先:不要使用.NET内置的压缩流类。它们有buggy,可以随机截断数据流末尾的字节。我一直在使用DotNetZip,效果很好:http://dotnetzip.codeplex.com/
现在,还有一些注意事项:
,
显然,围绕响应过滤和写入输出流有很多不同的问题。使用Reflector和大量的实验,这是我到目前为止找到的最好的(“最佳”是在各种场景下正确工作)的解决方案:
new StreamReader(fileStream, new BinaryEncoding(), false)打开您的文件。这个"false“参数非常重要,它会阻止charI've found that 32KB is a good size.的StreamReader获取字节顺序标记并覆盖缓冲区
然后,在一个循环中:
int n = StreamReader.Read(buffer, 0, buffer.Length);
Response.Write(buffer, 0, n);
Response.Flush();直到n为0。
注意:此方法会导致相当高的CPU使用率。在100兆局域网上,单个客户端以10MB/秒的速度下载时,一个核心上的CPU使用率约为40-50%。我希望我能找到更好的方法..。如果我有Reflector Pro,我也许能找到一个。
发布于 2010-08-12 02:37:23
如果您使用的是IIS7或IIS7.5,我建议您使用HTTP Compression模块,而不是使用自己的模块。这可能有助于解决这个问题。
http://technet.microsoft.com/en-us/library/cc771003(WS.10).aspx
https://stackoverflow.com/questions/3445479
复制相似问题