C# 条件压缩
我最近插入了一个自定义编码器(使用二进制编码器进行实际编码,使用Gzip压缩程序压缩字节数组)。它很好用。现在的问题是,对于较小的消息大小,它实际上会使字节数组膨胀。我想知道是否有办法避免这种情况。特别是如果有一种方法可以应用条件压缩和解压缩 我确实试着做了一些类似的事情——设置一个条件C# 条件压缩,c#,wcf,c#-4.0,C#,Wcf,C# 4.0,我最近插入了一个自定义编码器(使用二进制编码器进行实际编码,使用Gzip压缩程序压缩字节数组)。它很好用。现在的问题是,对于较小的消息大小,它实际上会使字节数组膨胀。我想知道是否有办法避免这种情况。特别是如果有一种方法可以应用条件压缩和解压缩 我确实试着做了一些类似的事情——设置一个条件 if(buffer.Count <= 5000) skip compression if(buffer.Count你能写一个字节来指示数据是否被压缩吗?0=未压缩,1=Gzip压缩,2-255=未来的
if(buffer.Count <= 5000)
skip compression
if(buffer.Count你能写一个字节来指示数据是否被压缩吗?0=未压缩,1=Gzip压缩,2-255=未来的压缩算法
您可以写入未压缩的长度,但这取决于服务器和客户端使用相同的截止长度不进行压缩。您可以写入一个布尔值,指示它是否被压缩,但这仍然需要一个完整的字节,并且您可以通过写入值0-255为将来的扩展留出空间。(也许您会发现,对于您的数据,不同的压缩算法可以提供更好的压缩。)如果您使用的是http,并且如果您使用的是IIS 7或更高版本(也可以使用IIS 6,但配置显然更难),您可以使用内置的gzip/deflate压缩
看
该链接还解释了诸如“minFileSizeForComp”之类的参数,这些参数正好解决了您的问题。它还有许多其他不错的参数,如“dynamicCompressionDisableCpuUsage”,一旦超过某个cpu负载,这些参数将禁用压缩
http压缩的好处在于它是一个标准,客户机和服务器可以使用标准http请求和响应头来确定每个请求是否可以或想要压缩。此外,压缩格式可以从gzip更改为deflate,后者有两个优点,尽管没有使用那么多。请参阅
及
一个潜在的缺点是,根据应用程序的不同,http压缩只能从服务器->客户端完成,因此,如果您的请求很大,这可能会成为一个问题,但在大多数情况下,服务器响应可能比客户端请求大得多。
编辑:如果您愿意添加一个,您甚至可以让请求压缩工作
我刚刚成功地将一个由20台服务器组成的大量使用的服务器场从GZIPMessageEncoder迁移到IIS7.5的http压缩
另一方面,请不要在缓冲传输模式下使用MS的GzipMessageEncoder示例,这是默认的。GzipMessageEncoder只会浪费大量内存—在我的特殊情况下,数百兆字节,请参见我的回答:您能为压缩的消息添加自定义头吗?@Mitch:这可能不起作用。因为我将我必须添加,比如我将自定义头添加到消息类并在WriteMessage()函数中压缩它。在ReadMessage()中,我必须在获取消息类并读取头之前解压缩它。
public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
{
ArraySegment<byte> decompressedBuffer = DecompressBuffer(buffer, bufferManager);
LogWrite("Decompressed from {0} bytes to {1} bytes", buffer.Count, decompressedBuffer.Count);
Message returnMessage = _innerEncoder.ReadMessage(decompressedBuffer, bufferManager);
returnMessage.Properties.Encoder = this;
return returnMessage;
}
public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)
{
var buffer = _innerEncoder.WriteMessage(message, maxMessageSize, bufferManager, messageOffset);
var compressedBuffer = CompressBuffer(buffer, bufferManager, messageOffset);
LogWrite("Compressed from {0} bytes to {1} bytes", buffer.Count, compressedBuffer.Count);
return compressedBuffer;
}