【问题标题】:How to compress a .net object instance using gzip如何使用 gzip 压缩 .net 对象实例
【发布时间】:2010-11-01 04:06:03
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: c# .net asp.net caching compression


    【解决方案1】:

    这不适用于任何引用类型。这适用于 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 将内容保存在内存中,而不是写入文件。不过,我怀疑这是否真的是一个有效的缓存解决方案。

    【讨论】:

    • 谢谢你,这真的很有帮助,解压缩会是什么样子......以前从未使用过 BinaryFormatter。
    • 感谢您轻松复制+粘贴到我的代码中。我经常格式化东西,现在这只是一个我可以在 Google 上轻松找到的 sn-p。 +1
    【解决方案2】:

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

    您可以使用BinaryFormatterGZipStream,或者您可以使用类似protobuf-net 序列化(免费)之类的东西,它已经非常紧凑(添加GZipStream 通常会使数据更大 - 这是密集二进制的典型特征)。特别是,像 protobuf-net 这样的东西的优点是您可以减小大小,而无需支付在反序列化期间解压缩它的 CPU 成本。在some tests之前添加GZipStream,它比BinaryFormatter快4倍。将额外的时间添加到 GZip 的 BinaryFormatter 上,它应该会以可观的优势获胜。

    【讨论】:

      【解决方案3】:

      我今天刚刚为我的应用添加了 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,以这种方式正确链接(解)压缩和(解)加密有点重要,因为在加密从数据中产生噪音之前,您会希望丢失熵。

      【讨论】:

        【解决方案4】:

        这是如何做到的。

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

        【讨论】:

          猜你喜欢
          • 2021-11-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-14
          • 2010-10-07
          相关资源
          最近更新 更多