C# 将ZipArchive与ASP.NET核心Web Api结合使用
问题是如何使用ASP.NET Core 2(当前)Web API动态创建压缩文件夹 我正在使用C# 将ZipArchive与ASP.NET核心Web Api结合使用,c#,asp.net-core,asp.net-core-webapi,ziparchive,C#,Asp.net Core,Asp.net Core Webapi,Ziparchive,问题是如何使用ASP.NET Core 2(当前)Web API动态创建压缩文件夹 我正在使用System.IO.Compression.ZipArchive 我曾在几篇博客文章中使用流或字节数组来实现这一点,所有这些都给了我相同的输出 我可以下载zip文件夹,但无法打开它 压缩的文件夹大小正确。即使它没有打开。 [HttpGet] [Route("/api/download/zip")] public async Task<IActionResult> Zip() { by
System.IO.Compression.ZipArchive
我曾在几篇博客文章中使用流或字节数组来实现这一点,所有这些都给了我相同的输出
我可以下载zip文件夹,但无法打开它
压缩的文件夹大小正确。即使它没有打开。
[HttpGet]
[Route("/api/download/zip")]
public async Task<IActionResult> Zip()
{
byte[] bytes = null;
using (MemoryStream zipStream = new MemoryStream())
using (var zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
{
var tempFileName = await _azure.GetFilesByRef("Azure_FilePath");
// Running just this line gives me the zipped folder (empty) which I can open
ZipArchiveEntry entry = zip.CreateEntry("File1.pdf", CompressionLevel.Fastest);
// Adding this 2nd section will download the zip but will not open the zip folder
using (Stream stream = entry.Open())
using (FileStream fs = new FileStream(tempFileName, FileMode.Open, FileAccess.Read))
{
await fs.CopyToAsync(stream);
}
bytes = zipStream.ToArray();
}
return File(bytes, MediaTypeNames.Application.Zip, $"Attachments{DateTime.Now.ToBinary()}.zip");
}
我希望它的工作方式是用户单击运行此操作的按钮并返回包含一个或多个文件的压缩文件夹。
[HttpGet]
[Route("/api/download/zip")]
public async Task<IActionResult> Zip()
{
byte[] bytes = null;
using (MemoryStream zipStream = new MemoryStream())
using (var zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
{
var tempFileName = await _azure.GetFilesByRef("Azure_FilePath");
// Running just this line gives me the zipped folder (empty) which I can open
ZipArchiveEntry entry = zip.CreateEntry("File1.pdf", CompressionLevel.Fastest);
// Adding this 2nd section will download the zip but will not open the zip folder
using (Stream stream = entry.Open())
using (FileStream fs = new FileStream(tempFileName, FileMode.Open, FileAccess.Read))
{
await fs.CopyToAsync(stream);
}
bytes = zipStream.ToArray();
}
return File(bytes, MediaTypeNames.Application.Zip, $"Attachments{DateTime.Now.ToBinary()}.zip");
}
[HttpGet]
[路由(“/api/download/zip”)]
公共异步任务Zip()
{
字节[]字节=null;
使用(MemoryStream zipStream=新的MemoryStream())
使用(var zip=new ZipArchive(zipStream,ZipArchiveMode.Create,true))
{
var tempFileName=await_azure.GetFilesByRef(“azure_FilePath”);
//只运行这行代码就可以打开压缩文件夹(空)
ZipArchiveEntry entry=zip.CreateEntry(“File1.pdf”,CompressionLevel.faster);
//添加此第2部分将下载zip,但不会打开zip文件夹
使用(Stream=entry.Open())
使用(FileStream fs=newfilestream(tempFileName,FileMode.Open,FileAccess.Read))
{
等待fs.CopyToAsync(流);
}
bytes=zipStream.ToArray();
}
返回文件(字节,MediaTypeNames.Application.Zip,$“附件{DateTime.Now.ToBinary()}.Zip”);
}
有人能发现错误或提出替代解决方案吗?在处理存档之前,所有数据都不会写入流。因此,在这种情况下,如果存档尚未刷新数据流,则数据流中的数据可能不完整
memoryStream.ToArray
在存档有机会将其所有数据刷新到底层流之前被调用
考虑重构以
//...
var tempFileName = await _azure.GetFilesByRef("Azure_FilePath");
using (MemoryStream zipStream = new MemoryStream()) {
using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Create, leaveOpen: true)) {
ZipArchiveEntry entry = archive.CreateEntry("File1.pdf", CompressionLevel.Fastest);
using (Stream stream = entry.Open())
using (FileStream fs = new FileStream(tempFileName, FileMode.Open, FileAccess.Read)) {
await fs.CopyToAsync(stream);
}
}// disposal of archive will force data to be written to memory stream.
zipStream.Position = 0; //reset memory stream position.
bytes = zipStream.ToArray(); //get all flushed data
}
//...
在您的示例中,假设FileStream
opened是所创建条目的正确文件类型;单个PDF文件。否则,请考虑从<代码> TestFrimeNe> <代码> > < /P>中提取名称。
您必须为要添加到存档中的每个项目添加一个唯一的条目(文件路径)。如果您直接从azure发送文件,是否有效?没有拉链?它是否适用于不是来自Azure的本地文件?zip的文件大小有意义吗?不清楚您是否正在尝试创建zip并将其发送到管道中,或者您是否正在尝试从azure获取zip并将其传递。您必须为要添加到存档中的每个项目添加一个条目。@poke是的,我可以直接从azure下载该文件,但这不是我想要的功能。我说的是以增量方式修改代码,以便您能够找出问题所在。