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

ASP.NET Core Web Api使用ZipArchive生成压缩包无法打开问题排查

解决ASP.NET Core 2 Web API中动态生成可打开压缩文件夹的问题

我一眼就发现了代码里的核心问题——你在ZipArchive的using块内部就调用了zipStream.ToArray(),这时候压缩归档还没完成最终的写入操作!

问题原因

当使用ZipArchiveMode.Create创建压缩包时,ZipArchive会在它被**释放(Dispose)**的时候才完成所有收尾工作:包括写入压缩包的目录结构、校验信息和结尾标记。如果在ZipArchive还没释放就读取底层的MemoryStream,得到的字节数组是不完整的,这就导致下载后的zip文件看起来大小正常,但实际上是损坏的,无法打开。

修正后的代码

把bytes = zipStream.ToArray()移到ZipArchive的using块外面,确保压缩归档完成所有写入后再提取数据:

[HttpGet]
[Route("/api/download/zip")]
public async Task<IActionResult> Zip()
{
    byte[] bytes = null;
    using (MemoryStream zipStream = new MemoryStream())
    {
        using (var zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
        {
            var tempFileName = await _azure.GetFilesByRef("Azure_FilePath");
            ZipArchiveEntry entry = zip.CreateEntry("File1.pdf", CompressionLevel.Fastest);
            
            using (Stream stream = entry.Open())
            using (FileStream fs = new FileStream(tempFileName, FileMode.Open, FileAccess.Read))
            {
                await fs.CopyToAsync(stream);
            }
        }
        // 等ZipArchive释放后,再读取完整的压缩数据
        bytes = zipStream.ToArray();
    }
    return File(bytes, MediaTypeNames.Application.Zip, $"Attachments{DateTime.Now.ToBinary()}.zip");
}

额外检查项

  • 确认tempFileName指向的文件确实存在,并且你的应用程序有读取该文件的权限
  • 如果需要添加多个文件,重复CreateEntry和文件复制的逻辑即可
  • 文件名中的DateTime.Now.ToBinary()可能会生成不太友好的文件名,建议换成更易读的格式,比如DateTime.Now.ToString("yyyyMMddHHmmss")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:13:40