一次下载多个 zip 格式的文件

Posted

技术标签:

【中文标题】一次下载多个 zip 格式的文件【英文标题】:Download multi files in zip format at once 【发布时间】:2018-09-18 18:43:05 【问题描述】:

我想创建一个循环来遍历我的数据库中具有特定 ID 的所有文件,并以zip-格式下载它们。每个文件都有一个名称。我想按名称 + timenow 将其保存在单个 zipfile 中。

//this code is working fine for single file
if (fileattach != null && fileattach.ContentLength > 0)
    fileattach.FileDownloadName = attach.name + System.DateTime.Now + ".jpg";
return fileattach; 

我尝试如下做,但我真的没有逻辑

public ActionResult downloadF(int? id) 
    var attach      = db.details.First(a => a.id == id);
    var fileattach  = new FileContentResult(attach.foto.ToArray(), "application/octet-stream");
    var fileattach2 = new FileContentResult(attach.passport.ToArray(), "application/octet-stream");
    var fileattach3 = new FileContentResult(attach.degree.ToArray(), "application/octet-stream");

    using (var memoryStream = new MemoryStream()) 
        using (var ziparchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) 
            for (int i = 0; i < 3; i++) 

                //how to define files object as we do in the upload by defining 
                //HttpPostedFileBase here it is not working
                HttpPostedFileBase Files.ElementAt(i) != null 
                ziparchive.CreateEntryFromFile(filesCol[i].name);
            
        

        return File(memoryStream.ToArray(), "application/zip", "Attachments.zip");
    

【问题讨论】:

HttpPostedFileBase 用于浏览器向您发送文件时。您不应该在这里使用它,因为您正在向浏览器 提供文件。 可以通过以下两种方式之一将数据库中的文件添加到 zip 文件中。 a) 您将它们保存到文件系统,然后将它们从那里添加到 zip 文件中。 b) 您可以通过Stream 将它们添加到 zip 文件中。你知道我说的Stream是什么意思吗? 如何对多文件使用流,我面临的问题是如何在如上图选择id时遍历数据库中的所有文件, 它是 var attach = db.details.Where(a => a.id == id); ,表示dbset在数据库中的确切行,下一步如何下载foto,passport,degree列中存在的任何文件 使用MemoryStream 而不是FileContentResult 【参考方案1】:

请参阅Creating a ZIP Archive in Memory Using System.IO.Compression 了解如何创建 zip 文件,您将使用文件找到一个答案,然后向下滚动以了解如何使用 memorystream 来完成此操作

所以你的代码看起来有点像,不是最优的,你可以为每种类型的文档创建一个帮助函数

public ActionResult downloadF(int? id)

    var attach = db.details.First(a => a.id == id);

    using (var memoryStream = new MemoryStream())
    
        using (var ziparchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
        
            AddToArchive(ziparchive, "foto.png", attach.foto.ToArray());
            AddToArchive(ziparchive, "passport.png", attach.passport.ToArray());
            AddToArchive(ziparchive, "degree.png", attach.degree.ToArray());
        
        return File(memoryStream.ToArray(), "application/zip", "Attachments.zip");
    


private void AddToArchive(ZipArchive ziparchive, string fileName, byte[] attach)

    var zipEntry = ziparchive.CreateEntry(fileName, CompressionLevel.Optimal);
    using (var zipStream = zipEntry.Open())
    using (var streamIn = new MemoryStream(attach))
    
        streamIn.CopyTo(zipStream);
    

【讨论】:

感谢您的建议,但它不处理数据库中的多个文件 那么你需要提供更多关于你的数据如何存储在你的数据库中的信息,我认为,一旦你可以使用上面文章中的代码从你的数据中创建你的 zip 我已经在数据库中拥有了以字节为单位的文件,var attach = db.details.Where(a => a.id == id);已设置指标,现在浏览所有文件并以 zip、照片、护照和学位格式下载它们...... 谢谢,答案很长,但它有效,只是在我使用它之前我必须添加扩展名和名称 谢谢 :-) ,我对示例进行了编辑,向您展示了具有良好功能和更少代码的版本,然后代码更具可读性

以上是关于一次下载多个 zip 格式的文件的主要内容,如果未能解决你的问题,请参考以下文章

以 csv 格式下载包含来自多个模型的数据的 zip 文件

如何在 Rails 5.x.x 应用程序中以 Zip 格式从 S3 下载多个文件?

zip.dl是啥格式

在 WebApp 中创建和下载巨大 ZIP(来自多个 BLOB)的最佳实践

Java实现打包压缩文件或文件夹生成zip以实现多文件批量下载

zip和tar的区别