You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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);
        }
    }
}

额外优化建议

  1. 优先选BZip2:如果你的场景对压缩率要求高于压缩速度,BZip2是更好的选择,它的压缩率通常能达到原始数据的1/5甚至更低(取决于日志内容的重复度)。
  2. 优化序列化:用Protobuf-net代替BinaryFormatter,能让原始字节数组缩小30%-50%,再配合压缩,最终体积会更小。
  3. 合理批量压缩:既然每日有100万行,可以考虑按合理批次(比如每1万行一组)压缩存储,既不会让单条记录过大,又能保证压缩效率。

内容的提问来源于stack exchange,提问作者lordvlad30

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:19:59