使用 SharpZipLib 压缩 C# 对象?

Compressing C# objects using SharpZipLib?

是否可以使用 SharpZipLib 压缩 List<T>? 将列表转换为字节数组可以得到大约 60000 个字节(未压缩)。

System.IO.Compression.DeflateStream 压缩它给我大约 1/3 的压缩率,但这远远不够。

目的是将集合作为 byte[] 存储在 (MS SQL) 数据库中,因为将它们保存为单独的行需要很多 space(100 万 rows/day).

谢谢

编辑:

List<ItemLog> itemLogs = new List<ItemLog>();
//populate with 1000 ItemLogs
byte[] array = null; //original byte array

BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, itemLogs);
array = ms.ToArray();

array 大小现在是 60000 字节

Zip the collection using a ZipOutputStream

MemoryStream outputMemoryStream = new MemoryStream();
ZipOutputStream zipStream = new ZipOutputStream(outputMemoryStream);

zipStream.SetLevel(3);

ZipEntry entry = new ZipEntry("logs");
entry.DateTime = DateTime.Now;

zipStream.PutNextEntry(entry);

StreamUtils.Copy(ms, zipStream, new byte[4096]);
zipStream.CloseEntry();

zipStream.IsStreamOwner = false;
zipStream.Close();

outputMemoryStream.Position = 0;

byte[] compressed = outputMemoryStream.ToArray();

compressed 现在大小为 164 字节。 <- 长度不是 valid/possible?

解压得到一个空数组。但由于压缩不对,我暂时跳过解压代码。

我在您的代码中没有发现任何真正的问题。唯一可能出现问题的部分是数据复制。输入数据流是否位于应该存储的数据开头?尝试添加以下行:

ms.Seek(0, SeekOrigin.Begin); // added line
StreamUtils.Copy(ms, zipStream, new byte[4096]);

根据您的代码,我编写了一个简单的压缩函数,它按预期工作。

private static byte[] Compress(byte[] source)
{
  byte[] compressed;
  using (var memory = new MemoryStream())
  using (var zipped = new ZipOutputStream(memory))
  {
    zipped.IsStreamOwner = false;
    zipped.SetLevel(9);
    var entry = new ZipEntry("data")
    {
      DateTime = DateTime.Now
    };
    zipped.PutNextEntry(entry);
#if true
    zipped.Write(source, 0, source.Length);
#else
    using (var src = new MemoryStream(source))
    {
      StreamUtils.Copy(src, zipped, new byte[4096]);
    }
#endif
    zipped.Close();
    compressed = memory.ToArray();
  }
#if false
  using (var file = new FileStream("test.zip", FileMode.Create, FileAccess.Write, FileShare.Read))
  {
    file.Write(compressed, 0, compressed.Length);
  }
#endif
  return compressed;
}

您有其他方法可以保存输出 (数组或流) 并且有禁用代码将压缩数据保存到文件 (以签入外部应用压缩数据的真实内容).

我测试的数据是一个256字节长的(数据,压缩率小),结果是407字节(文件).

尝试使用数组,或者查看保存的流内容。