【问题标题】:Creating Zip Files from Memory Stream C#从内存流 C# 创建 Zip 文件
【发布时间】:2012-04-18 05:21:56
【问题描述】:

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

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

这是我的代码:

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 - 用于压缩

谢谢, 卡维塔

【问题讨论】:

  • 您找到解决方案了吗?我需要做同样的事情。
  • 不,我没有......我在网上尝试了所有解决方案,但没有任何效果......希望你能找到它
  • 此链接可能会有所帮助:snipplr.com/view/47762

标签: c# zip memorystream


【解决方案1】:

此链接描述了如何使用 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;
}

【讨论】:

  • 感谢您的回答,因为它也对我有用。你能告诉我如何压缩文本文件吗?
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    此代码将帮助您通过多个 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.压缩; System.IO.Compression.ZipArchive;

    【讨论】:

      【解决方案4】:

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

      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;
      

      【讨论】:

        【解决方案5】:

        以下代码是从 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.压缩;
        • System.IO.Compression.ZipArchive;
        • Microsoft.Azure.Storage;
        • Microsoft.Azure.Storage.Blob;

        【讨论】:

          【解决方案6】:

          我使用了来自该线程的信息,但决定发布我的端到端代码,因为它包含了下载后端服务器生成的 zip 文件的所有元素。

          前端 javascript Angular 12

          `

          export class downloadDocs{
            fileName:string = '';
            docs:string[] = [];
          }
          
          let docs = new downloadDocs();
          //do some code to put names in docs.docs;
          
          docs.fileName = 'download.zip';
          this.http.post('api/docs/download', docs,
          { responseType: 'arraybuffer' }).subscribe(zip => {
            let blob = new Blob([zip], { type: "application/octetstream" });
          
            let url = window.URL || window.webkitURL;
            let link = url.createObjectURL(blob);
            let a = $("<a />");
            a.attr("download", this.baseFileName() + '.zip');
            a.attr("href", link);
            $("body").append(a);
            a[0].click();
            $("body").remove(a);
          },
          error => {
            //however you handle errors
          }
          

          ` Azure 应用服务中的 web api core 5 C# 后端。全内存解决方案有效,因为我根本不必使用任何文件资源。使用了 SharpLibZip 包。

          `

          \\drives me nuts in code examples nobody includes the libraries
          \\spend lot of time hunting down namespaces
          using System.IO;
          using System.Threading.Tasks;
          using System.Collections.Generic;
          using ICSharpCode.SharpZipLib.Zip;
          using Microsoft.AspNetCore.Http;
          
          public class DownloadDocs{
          
              public string FileName = "";
          
              public List<string> Docs = new List<string>(); 
          }
          
          [Route("/api/docs/download")]
          [HttpPost]
          public async Task<ActionResult> ApiDownloadDocs([FromBody] DownloadDocs docs)
          {
            
            try
            {
                var stream = await this.ReturnZipFile(docs.Docs);
                return File(stream, "application/octet-stream", docs.FileName);
            }
            catch (Exception e)
            {
                var msg = $"Docs Download error: {e.Message}";
                return Problem(msg);
            }
          }
          
          private async Task<MemoryStream> ReturnZipFile(List<string> files)
          {
            var stream = new MemoryStream();
            stream.Position = 0;
            var zipOutputStream = new ZipOutputStream(stream);
            zipOutputStream.SetLevel(4); //Set the compression level(0-9)
          
            foreach (let doc in files)
            {
                var docStream = new MemoryStream();
                docStream = await this.GetPdfMemoryStream(doc);
                byte[] buffer = new byte[docStream.Length];
                int byteRead = 0;
          
                ZipEntry entry = new ZipEntry(doc + ".pdf");
                zipOutputStream.PutNextEntry(entry);
                while ((byteRead = docStream.Read(buffer, 0, buffer.Length)) > 0)
                    zipOutputStream.Write(buffer, 0, byteRead);
          
                docStream.Close();
            }
          
            zipOutputStream.Finish();
            //zipOutputStream.Close(); //this also closed the output stream and made it worthless
            
            stream.Position = 0;
            return stream;
          }
          

          `

          Sql Server 代码从表中读取 blob 并将其作为字节数组返回,然后返回内存流。

          `

          public async Task<byte[]> GetPdfBytes(string uuid)
          {
              byte[] fileBytes = null;
              var conn = new SqlConnection(connectionString);
              await conn.OpenAsync();
          
              string sql = $"SELECT CONVERT(varbinary(max),BLOB)  FROM DOC_BLOBS WHERE UUID = '{uuid}'";
              using (var cmd = new SqlCommand(sql, conn))
              {
                  using (var reader = await cmd.ExecuteReaderAsync())
                  {
                      if (await reader.ReadAsync())
                      {
                          fileBytes = (byte[])reader[0];
                      }
                  }
              }
              return fileBytes;
          }
          
          public async Task<MemoryStream> GetPdfMemoryStream(string uuid)
          {
              return new MemoryStream(await GetPdfBytes(uuid));
          }
          

          `

          【讨论】:

            猜你喜欢
            • 2016-09-23
            • 1970-01-01
            • 1970-01-01
            • 2022-06-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多