将ZipArchive与ASP.NET Core Web Api结合使用 [英] Using ZipArchive with ASP.NET Core Web Api

查看:528
本文介绍了将ZipArchive与ASP.NET Core Web Api结合使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题是如何使用ASP.NET Core 2(当前)Web API动态创建一个压缩(压缩)文件夹?

The question is how can I create a zipped (compressed) folder on the fly using ASP.NET Core 2 (currently) Web API?

我正在使用System.IO.Compression.ZipArchive

我有好几篇博客文章都是使用流或字节数组来完成的,它们都给我相同的输出.

I have been several blog posts where this is done using streams or byte arrays, all give me the same output.

我能够下载zip文件夹,但是无法打开它.

I am able to download the zip folder but unable to open it.

压缩后的文件夹大小正确.即使它没有打开.

我希望它们起作用的方式是,用户单击运行此操作的按钮并返回包含一个或多个文件的压缩文件夹.

[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");
}

任何人都可以发现错误或提出替代解决方案吗?

Can anyone spot a mistake or suggest an alternative solution?

推荐答案

在处置档案之前,所有数据都不会写入流中.因此,在这种情况下,如果存档尚未清除流中的数据,则该数据可能不完整.

All the data is not written to the stream until the archive is disposed. So in this case, the data in the stream may be incomplete if the archive has not flushed it as yet.

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是所创建条目的正确文件类型; 单个 PDF 文件.否则,请考虑从tempFileName中提取名称.

The assumption in your example is also that the FileStream opened is the correct file type of the created entry; A single PDF file. Otherwise consider extracting a name from the tempFileName.

您必须为要添加到存档中的每个项目添加唯一的条目(文件路径).

You have to add a unique entry (file path) for each item you want added to the archive.

这篇关于将ZipArchive与ASP.NET Core Web Api结合使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆