从内存流 C# 创建 Zip 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10012178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 12:08:17  来源:igfitidea点击:

Creating Zip Files from Memory Stream C#

c#zipmemorystream

提问by Arshya

Basically the user should be able to click on one link and download multiple pdf files. But the Catch is I cannot create files on server or anywhere. Everything has to be in memory.

基本上,用户应该能够单击一个链接并下载多个 pdf 文件。但问题是我无法在服务器或任何地方创建文件。一切都必须在记忆中。

I was able to create memory stream and Response.Flush() it as pdf but how do I zip multiple memory streams without creating files.

我能够创建内存流和 Response.Flush() 它作为 pdf 但如何在不创建文件的情况下压缩多个内存流。

Here is my code:

这是我的代码:

Response.ContentType = "application/zip";

// If the browser is receiving a mangled zipfile, IIS Compression may cause this problem. Some members have found that
// Response.ContentType = "application/octet-stream" has solved this. May be specific to Internet Explorer.
Response.AppendHeader("content-disposition", "attachment; filename=\"Download.zip\"");
Response.CacheControl = "Private";
Response.Cache.SetExpires(DateTime.Now.AddMinutes(3)); // or put a timestamp in the filename in the content-disposition                

byte[] abyBuffer = new byte[4096];

ZipOutputStream outStream = new ZipOutputStream(Response.OutputStream);
outStream.SetLevel(3);

#region Repeat for each Memory Stream
MemoryStream fStream = CreateClassroomRoster();// This returns a memory stream with pdf document

ZipEntry objZipEntry = new ZipEntry(ZipEntry.CleanName("ClassroomRoster.pdf"));
objZipEntry.DateTime = DateTime.Now;
objZipEntry.Size = fStream.Length;
outStream.PutNextEntry(objZipEntry);

int count = fStream.Read(abyBuffer, 0, abyBuffer.Length);
while (count > 0)
{
    outStream.Write(abyBuffer, 0, count);
    count = fStream.Read(abyBuffer, 0, abyBuffer.Length);
    if (!Response.IsClientConnected)
        break;

    Response.Flush();
}

fStream.Close();

#endregion

outStream.Finish();
outStream.Close();

Response.Flush();
Response.End();

This creates a zip file but there's no file inside it

这将创建一个 zip 文件,但其中没有文件

I am using using iTextSharp.text - for creating pdf using ICSharpCode.SharpZipLib.Zip - for Zipping

我正在使用 iTextSharp.text - 使用 ICSharpCode.SharpZipLib.Zip 创建 pdf - 用于压缩

Thanks, Kavita

谢谢,卡维塔

采纳答案by Kris

This link describes how to create a zip from a MemoryStream using SharpZipLib: https://github.com/icsharpcode/SharpZipLib/wiki/Zip-Samples#wiki-anchorMemory. Using this and iTextSharp, I was able to zip multiple PDF files that were created in memory.

此链接描述了如何使用 SharpZipLib 从 MemoryStream 创建 zip:https: //github.com/icsharpcode/SharpZipLib/wiki/Zip-Samples#wiki-anchorMemory。使用它和 iTextSharp,我能够压缩在内存中创建的多个 PDF 文件。

Here is my code:

这是我的代码:

MemoryStream outputMemStream = new MemoryStream();
ZipOutputStream zipStream = new ZipOutputStream(outputMemStream);

zipStream.SetLevel(3); //0-9, 9 being the highest level of compression
byte[] bytes = null;

// loops through the PDFs I need to create
foreach (var record in records)
{
    var newEntry = new ZipEntry("test" + i + ".pdf");
    newEntry.DateTime = DateTime.Now;

    zipStream.PutNextEntry(newEntry);

    bytes = CreatePDF(++i);

    MemoryStream inStream = new MemoryStream(bytes);
    StreamUtils.Copy(inStream, zipStream, new byte[4096]);
    inStream.Close();
    zipStream.CloseEntry();
}

zipStream.IsStreamOwner = false;    // False stops the Close also Closing the underlying stream.
zipStream.Close();          // Must finish the ZipOutputStream before using outputMemStream.

outputMemStream.Position = 0;

return File(outputMemStream.ToArray(), "application/octet-stream", "reports.zip");

The CreatePDF Method:

CreatePDF 方法:

private static byte[] CreatePDF(int i)
{
    byte[] bytes = null;
    using (MemoryStream ms = new MemoryStream())
    {
        Document document = new Document(PageSize.A4, 25, 25, 30, 30);
        PdfWriter writer = PdfWriter.GetInstance(document, ms);
        document.Open();
        document.Add(new Paragraph("Hello World " + i));
        document.Close();
        writer.Close();
        bytes = ms.ToArray();
    }

    return bytes;
}

回答by mrosiak

You could generate your pdf files and store it in IsolatedStorageFileStream then you could zip content from that storage.

您可以生成 pdf 文件并将其存储在 IndependentStorageFileStream 中,然后您可以从该存储中压缩内容。

回答by Skull

This code Will help You in Creating Zip by multiple pdf files which you will get Each file from a Download Link.

此代码将帮助您通过多个 pdf 文件创建 Zip,您将从下载链接中获取每个文件。

        using (var outStream = new MemoryStream())
                {
                    using (var archive = new ZipArchive(outStream, ZipArchiveMode.Create, true))
                    {
                        for (String Url in UrlList)
                        {
                            WebRequest req = WebRequest.Create(Url);
                            req.Method = "GET";
                            var fileInArchive = archive.CreateEntry("FileName"+i+ ".pdf", CompressionLevel.Optimal);
                            using (var entryStream = fileInArchive.Open())
                            using (WebResponse response = req.GetResponse())
                            {
                                using (var fileToCompressStream = response.GetResponseStream())
                                {
                                    entryStream.Flush();
                                    fileToCompressStream.CopyTo(entryStream);
                                    fileToCompressStream.Flush();
                                }
                            }
                           i++;
                        }

                    }
                    using (var fileStream = new FileStream(@"D:\test.zip", FileMode.Create))
                    {
                        outStream.Seek(0, SeekOrigin.Begin);
                        outStream.CopyTo(fileStream);
                    }
                }

Namespace Needed: System.IO.Compression; System.IO.Compression.ZipArchive;

需要的命名空间: System.IO.Compression;System.IO.Compression.ZipArchive;

回答by Sheo Dayal Singh

Below is the code which is creating a zip file in MemoryStream using ZipOutputStream class which is exists inside ICSharpCode.SharpZipLib dll.

下面是使用存在于 ICSharpCode.SharpZipLib dll 中的 ZipOutputStream 类在 MemoryStream 中创建 zip 文件的代码。

FileStream fileStream = File.OpenRead(@"G:.pdf");
MemoryStream MS = new MemoryStream();

byte[] buffer = new byte[fileStream.Length];
int byteRead = 0;

ZipOutputStream zipOutputStream = new ZipOutputStream(MS);
zipOutputStream.SetLevel(9); //Set the compression level(0-9)
ZipEntry entry = new ZipEntry(@"1.pdf");//Create a file that is needs to be compressed
zipOutputStream.PutNextEntry(entry);//put the entry in zip

//Writes the data into file in memory stream for compression 
while ((byteRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
    zipOutputStream.Write(buffer, 0, byteRead);

zipOutputStream.IsStreamOwner = false;
fileStream.Close();
zipOutputStream.Close();
MS.Position = 0;

回答by Guilherme Flores

Below code is to get files from a directory in azure blob storage, merge in a zip and save it in azure blob storage again.

下面的代码是从 azure blob 存储中的目录中获取文件,合并成 zip 并再次将其保存在 azure blob 存储中。

var outputStream = new MemoryStream(); var archive = new ZipArchive(outputStream, ZipArchiveMode.Create, true);

var outputStream = new MemoryStream(); var archive = new ZipArchive(outputStream, ZipArchiveMode.Create, true);

    CloudBlobDirectory blobDirectory = appDataContainer.GetDirectoryReference(directory);

    var blobs = blobDirectory.ListBlobs();

    foreach (CloudBlockBlob blob in blobs)
    {
        var fileArchive = archive.CreateEntry(Path.GetFileName(blob.Name),CompressionLevel.Optimal);

        MemoryStream blobStream = new MemoryStream();
        if (blob.Exists())
        {
            blob.DownloadToStream(blobStream);
            blobStream.Position = 0;
        }

        var open = fileArchive.Open();
        blobStream.CopyTo(open);
        blobStream.Flush();
        open.Flush();
        open.Close();

        if (deleteBlobAfterUse)
        {
            blob.DeleteIfExists();
        }
    }
    archive.Dispose();

    CloudBlockBlob zipBlob = appDataContainer.GetBlockBlobReference(zipFile);

    zipBlob.UploadFromStream(outputStream);

Need the namespaces:

需要命名空间:

  • System.IO.Compression;
  • System.IO.Compression.ZipArchive;
  • Microsoft.Azure.Storage;
  • Microsoft.Azure.Storage.Blob;
  • System.IO.压缩;
  • System.IO.Compression.ZipArchive;
  • Microsoft.Azure.Storage;
  • Microsoft.Azure.Storage.Blob;