如何用SharpZipLib压缩C#中的List<T>对象?
用SharpZipLib压缩List的可行方案及优化建议
当然可以用SharpZipLib来压缩你的List<ItemLog>!它支持多种压缩算法(比如ZIP、GZIP、BZip2),其中BZip2的压缩率通常比System.IO.Compression.DeflateStream高出不少,刚好能解决你当前压缩率不达标的问题。下面我给你一步步讲具体怎么实现:
第一步:先把List序列化为字节数组
SharpZipLib是处理字节流的工具,所以首先得把你的List<ItemLog>转换成二进制数组。这里要注意你的ItemLog类必须标记[Serializable]特性,不然序列化会失败。
基础的序列化示例用BinaryFormatter:
using System.IO; using System.Runtime.Serialization.Formatters.Binary; // 先确保ItemLog类标记了[Serializable] [Serializable] public class ItemLog { // 你的类属性,比如: public int Id { get; set; } public DateTime LogTime { get; set; } public string Content { get; set; } } // 序列化List<ItemLog>为字节数组 byte[] SerializeList(List<ItemLog> logs) { using (var ms = new MemoryStream()) { var formatter = new BinaryFormatter(); formatter.Serialize(ms, logs); return ms.ToArray(); } }
小提示:如果想要更小的原始字节数组(进一步提升压缩效果),可以用更高效的序列化库比如Protobuf-net,它序列化出来的体积比
BinaryFormatter小很多,而且速度更快。
第二步:用SharpZipLib进行高压缩率压缩
这里推荐用BZip2算法,它的压缩率比Deflate高不少,适合你的场景。先确保你已经通过NuGet安装了SharpZipLib(Install-Package SharpZipLib)。
压缩代码示例:
using ICSharpCode.SharpZipLib.BZip2; byte[] CompressWithBZip2(byte[] rawData) { using (var outputMs = new MemoryStream()) { // 使用BZip2OutputStream,默认就是高压缩级别 using (var bzipStream = new BZip2OutputStream(outputMs)) { bzipStream.Write(rawData, 0, rawData.Length); } return outputMs.ToArray(); } }
如果想要用ZIP格式(支持手动配置最高压缩级别),也可以这样写:
using ICSharpCode.SharpZipLib.Zip; byte[] CompressWithZip(byte[] rawData) { using (var outputMs = new MemoryStream()) { using (var zipStream = new ZipOutputStream(outputMs)) { // 设置最高压缩级别(0-9,9为最高) zipStream.SetLevel(9); // 添加一个条目(ZIP是容器格式,需要至少一个条目) var entry = new ZipEntry("logs") { DateTime = DateTime.Now }; zipStream.PutNextEntry(entry); zipStream.Write(rawData, 0, rawData.Length); zipStream.CloseEntry(); } return outputMs.ToArray(); } }
第三步:解压还原List
存到数据库后,你肯定还需要把压缩后的字节数组还原成原始列表,这里是对应的解压代码:
BZip2解压示例
List<ItemLog> DecompressBZip2(byte[] compressedData) { using (var inputMs = new MemoryStream(compressedData)) using (var bzipStream = new BZip2InputStream(inputMs)) using (var outputMs = new MemoryStream()) { bzipStream.CopyTo(outputMs); outputMs.Position = 0; var formatter = new BinaryFormatter(); return (List<ItemLog>)formatter.Deserialize(outputMs); } }
ZIP解压示例
List<ItemLog> DecompressZip(byte[] compressedData) { using (var inputMs = new MemoryStream(compressedData)) using (var zipStream = new ZipInputStream(inputMs)) { // 获取第一个(也是唯一的)条目 var entry = zipStream.GetNextEntry(); using (var outputMs = new MemoryStream()) { zipStream.CopyTo(outputMs); outputMs.Position = 0; var formatter = new BinaryFormatter(); return (List<ItemLog>)formatter.Deserialize(outputMs); } } }
额外优化建议
- 优先选BZip2:如果你的场景对压缩率要求高于压缩速度,BZip2是更好的选择,它的压缩率通常能达到原始数据的1/5甚至更低(取决于日志内容的重复度)。
- 优化序列化:用Protobuf-net代替
BinaryFormatter,能让原始字节数组缩小30%-50%,再配合压缩,最终体积会更小。 - 合理批量压缩:既然每日有100万行,可以考虑按合理批次(比如每1万行一组)压缩存储,既不会让单条记录过大,又能保证压缩效率。
内容的提问来源于stack exchange,提问作者lordvlad30
相关产品推荐
相关产品推荐

