如何使用gzip压缩.net对象实例

我想在将数据库的QUERYS添加到缓存之前压缩结果。

我希望能够压缩任何引用类型。

我有一个用于压缩字符串的工作版本..这个想法基于scott hanselman的博客文章http://shrinkster.com/173t

任何压缩.net对象的想法?

我知道它将是一个只读缓存,因为缓存中的对象只是字节数组。

这不适用于任何参考类型。 这适用于Serializable类型。 将BinaryFormatter连接到通过管道传输到文件的压缩流:

 var formatter = new BinaryFormatter(); using (var outputFile = new FileStream("OutputFile", FileMode.CreateNew)) using (var compressionStream = new GZipStream( outputFile, CompressionMode.Compress)) { formatter.Serialize(compressionStream, objToSerialize); compressionStream.Flush(); } 

您可以使用MemoryStream将内容保存在内存中,而不是写入文件。 但我怀疑这对缓存来说真的是一个有效的解决方案。

你在缓存中放入了什么类型的对象? 他们是打字对象吗? 或者像DataTable这样的东西? 对于DataTable ,则可能存储为通过GZipStream压缩的xml。 对于类型(实体)对象,您可能需要序列化它们。

您可以使用BinaryFormatterGZipStream ,或者您可以使用类似protobuf-net serialization(free)的东西,它已经非常紧凑(添加GZipStream通常会使数据更大 – 这是典型的密集二进制)。 特别是,protobuf-net之类的优势在于,无需支付在反序列化过程中解压缩的CPU成本,您就可以减小尺寸。 在添加GZipStream 之前的 一些测试中 ,它比BinaryFormatter快4倍。 将额外的时间添加到BinaryFormatter for GZip上,它应该赢得相当大的利润。

我今天刚刚为我的应用添加了GZipStream支持,所以我可以在这里分享一些代码;

连载:

 using (Stream s = File.Create(PathName)) { RijndaelManaged rm = new RijndaelManaged(); rm.Key = CryptoKey; rm.IV = CryptoIV; using (CryptoStream cs = new CryptoStream(s, rm.CreateEncryptor(), CryptoStreamMode.Write)) { using (GZipStream gs = new GZipStream(cs, CompressionMode.Compress)) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(gs, _instance); } } } 

反序列化:

 using (Stream s = File.OpenRead(PathName)) { RijndaelManaged rm = new RijndaelManaged(); rm.Key = CryptoKey; rm.IV = CryptoIV; using (CryptoStream cs = new CryptoStream(s, rm.CreateDecryptor(), CryptoStreamMode.Read)) { using (GZipStream gs = new GZipStream(cs, CompressionMode.Decompress)) { BinaryFormatter bf = new BinaryFormatter(); _instance = (Storage)bf.Deserialize(gs); } } } 

注意:如果您使用CryptoStream,以这种方式链接(取消)压缩和(解密)加密是很重要的,因为在加密会从数据中产生噪声之前,您将希望丢失熵。

以下是如何做到这一点。

GzipStream :提供用于压缩和解压缩流的方法和属性。

使用binaryformatter将对象序列化为内存流,并将该内存流挂钩到Gzipstream。

压缩代码如下:

  public static byte[] ObjectToCompressedByteArray(object obj) { try { using (var memoryStream = new System.IO.MemoryStream()) { using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress)) { var binaryFormatter = new BinaryFormatter(); binaryFormatter.Serialize(gZipStream, obj); } return memoryStream.ToArray(); } } catch (Exception ex) { LoggerWrapper.CMLogger.LogMessage( $"EXCEPTION: BSExportImportHelper.ObjectToByteArray - : {ex.Message}", LoggerWrapper.CMLogger.CMLogLevel.Error); throw; } }