使用 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字节(文件).
尝试使用数组,或者查看保存的流内容。
是否可以使用 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字节(文件).
尝试使用数组,或者查看保存的流内容。