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

ASP.NET Core用流压缩文件上传Azure Blob Storage后下载无法打开怎么办

问题根因
  • 核心错误是ZipArchive的生命周期操作顺序错误:使用ZipArchiveMode.Create模式创建压缩包时,只有当ZipArchive对象完成释放(即离开其对应的using代码块)后,才会将Zip文件的完整收尾结构(比如中央目录记录、文件索引等元数据)写入目标流。你当前的代码将流复位、上传的逻辑都写在ZipArchive的using块内部,此时上传的流仅包含打包的文件内容,缺少Zip格式必须的元数据,因此生成的文件是损坏的,无法被解压工具识别。
  • 次要可优化点:上传Blob时未指定正确的Content-Type,也没有给Blob加.zip后缀,部分场景下会导致下载后的文件识别异常。
修正后的代码
var moduleVersionReleaseFiles = _appDbContext
    .ModuleVersionReleaseFile
    .Where(x => x.ModuleVersionReleaseId == moduleVersionReleaseId)
    .ToList();

string AzureBlobStorageConfig = _configuration["AzureBlobStorage"];
var connectionString = _configuration["StorageConnectionString"];
string containerName = moduleVersionReleaseId + "-" + Guid.NewGuid().ToString();

BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
BlobContainerClient containerClient = await blobServiceClient.CreateBlobContainerAsync(containerName.ToLowerInvariant(), Azure.Storage.Blobs.Models.PublicAccessType.BlobContainer);

// 给Blob加上.zip后缀,避免系统识别格式错误
BlobClient blobClient = containerClient.GetBlobClient($"{moduleVersionReleaseId}.zip");

using var stream = new MemoryStream();
// 增加leaveOpen: true参数,避免ZipArchive释放时连带关闭底层流,影响后续上传
using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true))
{
    foreach (var moduleVersionReleaseFile in moduleVersionReleaseFiles)
    {
        var entry = archive.CreateEntry(moduleVersionReleaseFile.File);
        using (var entryStream = entry.Open())
        // 用Path.Combine拼接路径,替代硬编码斜杠,适配不同操作系统
        using (var fileStream = File.OpenRead(Path.Combine(moduleVersionReleaseFile.Path, moduleVersionReleaseFile.File)))
        {
            await fileStream.CopyToAsync(entryStream);
        }
    }
}
// 等Zip打包完全完成、ZipArchive释放后,再复位流执行上传
stream.Position = 0;
// 上传时指定Zip格式的ContentType,可选但建议添加
await blobClient.UploadAsync(stream, new Azure.Storage.Blobs.Models.BlobHttpHeaders 
{ 
    ContentType = "application/zip" 
}, overwrite: true);

return blobClient.Uri.ToString();
本地验证方案

无需登录Azurite后台即可校验打包逻辑:在上传代码前新增逻辑,将复位后的stream写入本地文件,确认本地生成的Zip可以正常打开后,再执行上传逻辑即可快速定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 05:48:01