【问题标题】:Download multiple files from Azure blob storage as zip file从 Azure Blob 存储下载多个文件作为 zip 文件
【发布时间】:2021-08-11 08:52:01
【问题描述】:

我尝试从 .NET Core 3.1 中的 Web API 下载多个文件,并将它们放入响应正文中编写的 zip 存档中。 当我使用浏览器下载 zip 文件时,zip 文件已损坏!

控制器:

public async Task DownloadFilesAsync([FromServices] IFileService fileService, [FromBody] IEnumerable<Guid> fileIds, Guid folderId)
{
    HttpContext.Response.Headers.Add("Content-Disposition", $"{DispositionTypeNames.Attachment};filename*=files.zip");
    HttpContext.Response.ContentType = MediaTypeNames.Application.Zip;
    await fileService.GetZipAsync(User.UserId(), folderId, fileIds, HttpContext.Response.Body);
}

服务:

public async Task GetZipAsync(Guid userId, Guid folderId, IEnumerable<Guid> fileIds, Stream stream)
{
    using (ZipArchive zip = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true))
    {
        foreach (Guid id in fileIds)
        {
            // metadata stored in a sql database, File is a custom type
            File file = await _fileRepository.GetFileAsync(folderId, id);
            using Stream entry = zip.CreateEntry(file.Name, CompressionLevel.Optimal).Open();
            await _fileStorage.WriteBlobAsync(userId, folderId, file.Name, entry);
        }
    }
}

存储库:

public async Task WriteBlobAsync(Guid userId, Guid folderId, string name, Stream output)
{
    BlobContainerClient container = Client.GetBlobContainerClient(userId.ToString());
    await container.GetBlobClient($"{folderId}/{name}").DownloadToAsync(output);
}

但下载的 zip 存档无法使用:

我做错了什么?

【问题讨论】:

    标签: c# asp.net-core-webapi azure-blob-storage


    【解决方案1】:

    好吧,我觉得自己在这个方面有点愚蠢......

    这段代码在背面非常好,我的问题出在客户端。

    我的 axios 请求配置中缺少 { responseType: 'arraybuffer' }...

    【讨论】:

      【解决方案2】:

      方法一。

      你可以尝试disposeZipArchive,错误应该会解决。

      public async Task GetZipAsync(Guid userId, Guid folderId, IEnumerable<Guid> fileIds, Stream stream)
      {
          using (ZipArchive zip = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true))
          {
              foreach (Guid id in fileIds)
              {
                  // metadata stored in a sql database, File is a custom type
                  File file = await _fileRepository.GetFileAsync(folderId, id);
                  using Stream entry = zip.CreateEntry(file.Name, CompressionLevel.Optimal).Open();
                  await _fileStorage.WriteBlobAsync(userId, folderId, file.Name, entry);
              }
              //I added this line 
              zip.Dispose();
          }
      }
      

      方法二。

      您可以将流的 AutoFlush 属性设置为 true。

      更多详情,您可以参考以下链接。

      ZipArchive gives Unexpected end of data corrupted error

      【讨论】:

      • 嗯? using 自动调用Dispose。两次处理 zip 会有什么帮助?
      • @Zer0 对不起,我添加了错误的地方。我更新了,试试看。
      • 这仍然是双重处置。那条线不需要存在。这就是 using 关键字的作用。
      • 从另一个线程中选择解决方案不是一个好习惯,我已经搜索过 sof 并没有找到任何可行的解决方案。链接的帖子已经过测试,但没有成功。就像 @Zer0 Dispose() 两次 ZipArchive 没有理由完成
      猜你喜欢
      • 2013-09-24
      • 2018-01-09
      • 1970-01-01
      • 2021-12-08
      • 2013-09-22
      • 2020-08-08
      相关资源
      最近更新 更多