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

如何在C#中创建含文件的zip归档并将其添加到外层zip压缩包

问题核心原因

你的代码存在两个逻辑错误:

  1. 外层总归档被放在分组循环内部,每次循环都会重新创建,直接覆盖之前写入的内容
  2. 内外两层ZipArchive共用了同一个MemoryStream,无法生成两个独立的zip结构

修正后的实现代码

// 提前创建总归档对应的内存流,全程只实例化一次
using var totalArchiveStream = new MemoryStream();
// 初始化总归档,开启leaveOpen保证流在归档释放后还能读取内容
using var totalArchive = new ZipArchive(totalArchiveStream, ZipArchiveMode.Create, true);

// 遍历日期分组
foreach (var (day, messagesPerDay) in messages.GroupBy(x => x.Date).ToDictionary(x => x.Key, x => x.ToList()))
{
    // 每个按日分组的子归档单独使用独立内存流
    using var dayArchiveStream = new MemoryStream();
    using (var dayArchive = new ZipArchive(dayArchiveStream, ZipArchiveMode.Create, true))
    {
        // 写入当日所有文件到子归档
        foreach (var message in messagesPerDay)
        {
            var fileEntry = dayArchive.CreateEntry(message.FileName, CompressionLevel.Fastest);
            var contentBytes = XmlHelper.SerializeWin1251(message).ToArray();
            
            using var entryStream = fileEntry.Open();
            entryStream.Write(contentBytes, 0, contentBytes.Length);
        }
    }

    // 子归档释放后结构已完整,写入到总归档中
    var dayZipEntry = totalArchive.CreateEntry($"{day:yyyy-MM-dd}.zip", CompressionLevel.NoCompression);
    using var dayZipEntryStream = dayZipEntry.Open();
    // 子归档流重置到起始位置再复制
    dayArchiveStream.Position = 0;
    dayArchiveStream.CopyTo(dayZipEntryStream);
}

// 必须先完全释放总归档,才能生成完整的zip尾部目录结构
totalArchive.Dispose();
// 最终总zip的字节数组,可用于保存到文件/接口返回等场景
var totalZipBytes = totalArchiveStream.ToArray();

注意说明

  • 子归档写入总归档时用CompressionLevel.NoCompression是因为子zip本身已经做过压缩,二次压缩不会明显缩小体积,还会额外消耗性能,你可以根据实际需求调整压缩等级。
  • 如果需要将最终结果写入本地文件,直接把totalZipBytes写入后缀为.zip的文件即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:39:04