我正在尝试在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" };
}
答案 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()
实例的进一步引用,以便垃圾收集器可以回收实例的内存,而不是保持活动以进行最终确定。
因为你想在写入后使用内存流,你需要确保它保持打开状态,并且将流的位置重置为开头,以便可以读取流的内容从一开始。