从byte []创建zip文件

Jus*_*son 46 .net c# asp.net-mvc zip .net-4.5

我试图从一系列字节数组创建.NET 4.5(System.IO.Compression)中的Zip文件.作为一个例子,从我使用的API我结束了一个List<Attachment>,并且每个Attachment有一个名为属性Body是一个byte[].如何迭代该列表并创建包含每个附件的zip文件?

现在我的印象是我必须将每个附件写入磁盘并从中创建zip文件.

//This is great if I had the files on disk
ZipFile.CreateFromDirectory(startPath, zipPath);
//How can I create it from a series of byte arrays?
Run Code Online (Sandbox Code Playgroud)

Jus*_*son 81

经过一段时间的游戏和阅读之后,我能够解决这个问题.以下是如何创建包含多个文件的zip文件(存档),而无需将任何临时数据写入磁盘:

using (var compressedFileStream = new MemoryStream())
//Create an archive and store the stream in memory.
using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Create, false)) {
    foreach (var caseAttachmentModel in caseAttachmentModels) {
        //Create a zip entry for each attachment
        var zipEntry = zipArchive.CreateEntry(caseAttachmentModel.Name);

        //Get the stream of the attachment
        using (var originalFileStream = new MemoryStream(caseAttachmentModel.Body))
        using (var zipEntryStream = zipEntry.Open()) {
            //Copy the attachment stream to the zip entry stream
            originalFileStream.CopyTo(zipEntryStream);
        }
    }

    return new FileContentResult(compressedFileStream.ToArray(), "application/zip") { FileDownloadName = "Filename.zip" };
}
Run Code Online (Sandbox Code Playgroud)

  • 友情提示 - 如果ZipArchive类不可用,请添加对程序集的引用:右键单击`References` - >`Add Reference`.在`Assemblies`下,搜索`System.IO`并检查`System.IO.Compression.FileSystem`和`System.IO.Compression`. (7认同)
  • @krillgar 你的编辑引入了一个错误。原始版本在“zipArchive”关闭后有 return 语句。通过删除嵌套,您现在还可以在“zipArchive”“using”语句中包含 return 语句。如果不处理,档案无效。 (4认同)
  • 什么是caseAttachmentModels?字节[]在哪里? (3认同)
  • 我用过这个,但是"compressedFileStream"总是在0长度......任何想法? (3认同)
  • @Zeph 是正确的。我必须在原始 using 语句周围添加大括号,并将 return 语句移出一层,以使 zipArchive 有效。 (3认同)
  • compressionFileStream始终为0个字节。请帮助我。 (2认同)

小智 5

这是 OP 发布的公认答案的变体。但是,这是针对 WebForms 而不是 MVC。我正在假设 caseAttachmentModel.Body 是一个字节 []

基本上所有内容都相同,只是有一个额外的方法将 zip 作为响应发送出去。

using (var compressedFileStream = new MemoryStream()) {
    //Create an archive and store the stream in memory.
    using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Update, false))         {
     foreach (var caseAttachmentModel in caseAttachmentModels) {
        //Create a zip entry for each attachment
        var zipEntry = zipArchive.CreateEntry(caseAttachmentModel.Name);

        //Get the stream of the attachment
        using (var originalFileStream = new MemoryStream(caseAttachmentModel.Body)) {
                using (var zipEntryStream = zipEntry.Open()) {
                    //Copy the attachment stream to the zip entry stream
                    originalFileStream.CopyTo(zipEntryStream);
                }
            }
        }
    }
    sendOutZIP(compressedFileStream.ToArray(), "FileName.zip");
}

private void sendOutZIP(byte[] zippedFiles, string filename)
{
    Response.Clear();
    Response.ClearContent();
    Response.ClearHeaders();
    Response.ContentType = "application/x-compressed";
    Response.Charset = string.Empty;
    Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
    Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
    Response.BinaryWrite(zippedFiles);
    Response.OutputStream.Flush();
    Response.OutputStream.Close();
    Response.End();
}
Run Code Online (Sandbox Code Playgroud)

我还想指出,@Levi Fuller 就已接受答案中的参考文献给出的建议是正确的!