C# 条件压缩

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=未来的

我最近插入了一个自定义编码器(使用二进制编码器进行实际编码,使用Gzip压缩程序压缩字节数组)。它很好用。现在的问题是,对于较小的消息大小,它实际上会使字节数组膨胀。我想知道是否有办法避免这种情况。特别是如果有一种方法可以应用条件压缩和解压缩

我确实试着做了一些类似的事情——设置一个条件

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;
        }