使用C#创建的ZipArchive不包含任何条目

时间:2018-05-14 23:57:43

标签: c# asp.net-mvc

我正在尝试在ASP.NET MVC中创建一个zip文件,其中包含一个PDF文件。但是,使用下面的代码,会创建一个空的zipfile。有人可以告诉我我做错了什么吗?

public FileResult DownloadZipfile(string html)
{
    MemoryStream memoryStream = new MemoryStream();
    ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true);

    byte[] rawDownload = PDFConverterUtils.PdfSharpConvert(html);

    ZipArchiveEntry entry = archive.CreateEntry("MyPDF.pdf");

    using (Stream entryStream = entry.Open())
    using (StreamWriter streamWriter = new StreamWriter(entryStream))
    {
        streamWriter.BaseStream.Write(rawDownload, 0, rawDownload.Length);
    }

    return new FileStreamResult(memoryStream, System.Net.Mime.MediaTypeNames.Application.Zip) { FileDownloadName = "test.zip" };

}

1 个答案:

答案 0 :(得分:5)

使用带有ZipArchive的{​​{1}}时,我建议在写入后重置流的位置,以便响应可以读取流的内容。

MemoryStream

正如在另一个答案中建议的那样,您应该处理存档以强制它将其内容写入其底层内存流,但请注意以下内容

  

ZipArchive.Dispose()

     

除非使用ZipArchive(Stream, ZipArchiveMode, Boolean)构造函数重载构造对象并将其public FileResult DownloadZipfile(string html) { byte[] rawDownload = PDFConverterUtils.PdfSharpConvert(html); MemoryStream memoryStream = new MemoryStream(); using(ZipArchive archive = new ZipArchive( stream: memoryStream, mode: ZipArchiveMode.Create, leaveOpen: true //To leave the memory stream open after disposal )){ ZipArchiveEntry entry = archive.CreateEntry("MyPDF.pdf"); using (Stream entryStream = entry.Open()) { entryStream.Write(rawDownload, 0, rawDownload.Length); } } memoryStream.Position = 0;//reset memory stream position for read return new FileStreamResult(memoryStream, System.Net.Mime.MediaTypeNames.Application.Zip) { FileDownloadName = "test.zip" }; } 参数设置为leaveOpen,否则所有基础流都将关闭,不再可用于后续写入操作。

     

完成true的此实例使用后,请调用ZipArchive以释放此实例使用的所有资源。您应该消除对此Dispose()实例的进一步引用,以便垃圾收集器可以回收实例的内存,而不是保持活动以进行最终确定。

因为你想在写入后使用内存流,你需要确保它保持打开状态,并且将流的位置重置为开头,以便可以读取流的内容从一开始。