从内存流C#创建Zip文件

时间:2012-04-04 13:31:48

标签: c# zip memorystream

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

我能够以PDF格式创建内存流和Response.Flush(),但如何在不创建文件的情况下压缩多个内存流。

这是我的代码:

    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();

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

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

谢谢, 卡维塔

5 个答案:

答案 0 :(得分:18)

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

这是我的代码:

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

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;

    }

答案 1 :(得分:1)

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

    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);

需要名称空间:

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

此代码将帮助您通过多个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);
                    }
                }

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

答案 4 :(得分:0)

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

FileStream fileStream = File.OpenRead(@"G:\1.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;