【问题标题】:.NET Core Web API return Zip File from memory stream.NET Core Web API 从内存流返回 Zip 文件
【发布时间】:2020-08-30 15:28:43
【问题描述】:

我正在尝试在内存中创建一个 Zip 文件,添加一些其他文件作为存档的条目,并使用以下命令从我的 Web API 控制器返回它:

try {
    // Create Zip Archive in Memory
    MemoryStream memoryStream = new MemoryStream();
    ZipArchive zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create);
    foreach(Worksheet w in worksheets) {
        string fullPath = Path.Combine(baseFolder, w.FilePathAndName);
        if(System.IO.File.Exists(fullPath)) {
            ZipArchiveEntry f = zipArchive.CreateEntry(w.FileName, CompressionLevel.Fastest);
            using(Stream entryStream = f.Open()) {
                FileStream fileStream = System.IO.File.OpenRead(fullPath);
                await fileStream.CopyToAsync(entryStream);
            }
        }
    }
    memoryStream.Seek(0, SeekOrigin.Begin);
    return File(memoryStream, "application/zip", $"Files.zip");
} catch(Exception e) {
    return StatusCode(500, "Error: Could not generate zip file");
}

这确实会创建并返回一个 zip 文件,但是它是无效的。 7-Zip gives me this error

运行unzip -t Files.zip 测试存档结果如下:

  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
note:  Files.zip may be a plain executable, not an archive
unzip:  cannot find zipfile directory in one of Files.zip or
        Files.zip.zip, and cannot find Files.zip.ZIP, period.

.NET Core 版本 3.1.201

【问题讨论】:

    标签: .net .net-core asp.net-core-webapi zipfile memorystream


    【解决方案1】:

    我发现了问题。

    我需要在memoryStream.Seek(0, SeekOrigin.Begin);之前致电zipArchive.Dispose()

    【讨论】:

    • 嘿,谢谢,我遇到了相反的问题,我的 zip 会在 7zip 中打开,但不能在文件资源管理器中打开,并且处理我的存档修复了它
    【解决方案2】:

    另一种选择是在 using 子句中使用 zipArchive,如下所示:

        using (var memoryStream = new MemoryStream())
                {
                    using (var zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
                    {
                        for (var i = 0; i < images.Count; i++)
                        {
                            var fileInArchive = zipArchive.CreateEntry(fileNames[i], CompressionLevel.Optimal);
                            using (var entryStream = fileInArchive.Open())
                            using (var fileToCompressStream = new MemoryStream(images[i]))
                            {
                                fileToCompressStream.CopyTo(entryStream);
                            }
                        }
                    }
    
                    using (var fileStream = new FileStream(zipPath, FileMode.Create))
                    {
                        memoryStream.Seek(0, SeekOrigin.Begin);
                        memoryStream.CopyTo(fileStream);
                    }
                }
    

    垃圾回收器会在退出 using 子句后自动销毁,无需显式调用 dispose。

    【讨论】:

      猜你喜欢
      • 2017-05-06
      • 2022-06-24
      • 1970-01-01
      • 2019-04-22
      • 1970-01-01
      • 2020-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多