c# - 如何压缩目录然后返回生成的字节数组,而无需在磁盘上物理创建 zip 文件?

标签 c# .net

请注意,我正在 .net MVC 项目中编写代码。

我有一个包含子目录和文件的目录(文件夹)。我的任务是编写一个返回压缩目录的 FileResult 的函数。
现在我的方法是这样的:

     ZipFile.CreateFromDirectory(originalFolder, zipFilePath); // this line create a zip file physically
     return File(zipFilePath,"application/zip",zipFileName);


一切正常,但我想知道是否可以有一种更快的方法直接通过 byte[] 从内存流中返回 FileResult。

上述方法要求我在函数调用后手动删除 zip 文件。此外,我假设 zip 文件的字节 [] 已经在函数中创建:ZipFile.CreateFromDirectory。将结果物理写入磁盘是不必要的。

我正在努力寻找一种新方法,来自 https://www.carlrippon.com/zipping-up-files-from-a-memorystream/ :
    byte[] fileBytes = null;

 using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream())
    {
        // create a zip
        using (System.IO.Compression.ZipArchive zip = new System.IO.Compression.ZipArchive(memoryStream, 
        System.IO.Compression.ZipArchiveMode.Create, true))
        {
            // interate through the source files
            foreach (SourceFile f in sourceFiles)
            {
                // add the item name to the zip
                System.IO.Compression.ZipArchiveEntry zipItem = zip.CreateEntry(f.Name + "." + f.Extension);
                // add the item bytes to the zip entry by opening the original file and copying the bytes
                using (System.IO.MemoryStream originalFileMemoryStream = new System.IO.MemoryStream(f.FileBytes))
                {
                    using (System.IO.Stream entryStream = zipItem.Open())
                    {
                        originalFileMemoryStream.CopyTo(entryStream);
                    }
                }
            }
        }
        fileBytes = memoryStream.ToArray();
    }
    return File(fileBytes, "application/zip");


但是上面的代码没有处理子目录问题。有人有想法吗?

最佳答案

您可以使用 DotNetZip Library这样做,下面是我为你写的asp.net mvc演示和链接。

Controller :

using System;
using System.Web.Mvc;
using System.Collections.Generic;
using Ionic.Zip;
using System.IO;

namespace ZipDemo
{
    public class HomeController : Controller
    {
        [HttpGet]
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public FileResult Download()
        {
            var bytes = default(byte[]);
            using (var zip = new ZipFile())
            {
                zip.AddEntry("text.txt", new byte[] {});
                zip.AddEntry("text\\text.txt", new byte[] {});

                using (var ms = new MemoryStream())
                {
                    zip.Save(ms);
                    bytes = ms.ToArray();
                } 
            }       
            return File(bytes, System.Net.Mime.MediaTypeNames.Application.Zip);
        }
    }
}

看法 :

@{
    Layout = null;
}

<!DOCTYPE html>
<html lang="en">
    <head>
        <!-- CSS Includes -->
        <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">  
    </head>
    <body>
        <div class="container">
            <div class="col-md-6 col-md-offset-3">
                <h1>Download ZIP</h1>
                @using (Html.BeginForm("Download","Home"))
                {

                    <input type="submit" class="btn btn-success submit" />
                }
            </div>
        </div>
    </body>
</html>


Online Demo Link ZipDoNet_MemoryStream | C# Online Compiler | .NET Fiddle

关于c# - 如何压缩目录然后返回生成的字节数组,而无需在磁盘上物理创建 zip 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59762713/

相关文章:

c# - nHibernate 的通用存储库

c# - 报告查看器 - 正常模式与打印预览模式不同

.net - 微服务和 .NET

c# - 代码契约检查线程亲和性——好主意?

C# 否定一个表达式

c# - 为什么这种继承不起作用?

c# - VS2013中选择 "debug"或 "release"方案配置有什么区别?

c# - HttpWebRequest 支持命名管道吗?

c# - 哪个由 C#.NET 的契约框架设计?

c# - 为什么自定义类型属性不能在泛型中继承?