6

我将 HttpListener 用于我自己的 http 服务器(我不使用 IIS)。我想通过 GZip 压缩来压缩我的 OutputStream:

byte[] refBuffer = Encoding.UTF8.GetBytes(...some data source...);

var varByteStream = new MemoryStream(refBuffer);

System.IO.Compression.GZipStream refGZipStream = new GZipStream(varByteStream, CompressionMode.Compress, false);

refGZipStream.BaseStream.CopyTo(refHttpListenerContext.Response.OutputStream);

refHttpListenerContext.Response.AddHeader("Content-Encoding", "gzip");

但我在 Chrome 中遇到错误:

ERR_CONTENT_DECODING_FAILED

如果我删除 AddHeader,那么它可以工作,但响应的大小似乎没有被压缩。我究竟做错了什么?

4

3 回答 3

10

问题是您的转移方向错误。您要做的是将 GZipStream 附加到 Response.OutputStream,然后在 MemoryStream 上调用 CopyTo,传入 GZipStream,如下所示:

refHttpListenerContext.Response.AddHeader("Content-Encoding", "gzip"); 

byte[] refBuffer = Encoding.UTF8.GetBytes(...some data source...); 

var varByteStream = new MemoryStream(refBuffer); 

System.IO.Compression.GZipStream refGZipStream = new GZipStream(refHttpListenerContext.Response.OutputStream, CompressionMode.Compress, false); 

varByteStream.CopyTo(refGZipStream); 
refGZipStream.Flush();
于 2011-09-16T01:57:23.887 回答
4

第一个问题(正如 Brent M Spell 提到的)是标题的错误位置。第二个是您没有正确使用 GZipStream。这个流需要一个“顶部”流来写入,这意味着一个空流(你用你的缓冲区填充它)。拥有一个空的“顶部”流,那么您所要做的就是在 GZipStream 上写入您的缓冲区。结果,内存流将被压缩内容填充。所以你需要类似的东西:

byte[] buffer = ....;

using (var ms = new MemoryStream())
{
    using (var zip = new GZipStream(ms, CompressionMode.Compress, true))
    zip.Write(buffer, 0, buffer.Length);
    buffer = ms.ToArray();
}

response.AddHeader("Content-Encoding", "gzip");
response.ContentLength64 = buffer.Length;

response.OutputStream.Write(buffer, 0, buffer.Length);
于 2012-06-06T23:59:47.217 回答
0

希望这可能会有所帮助,他们讨论了如何让 GZIP 工作。

C# 中的套接字:如何获取响应流?

于 2011-09-16T05:11:29.847 回答