【问题标题】:Creating a ZIP archive in memory using System.IO.Compression使用 System.IO.Compression 在内存中创建 ZIP 存档
【发布时间】:2013-06-18 10:01:59
【问题描述】:

我正在尝试使用MemoryStream 创建一个包含简单演示文本文件的 ZIP 存档,如下所示:

using (var memoryStream = new MemoryStream())
using (var archive = new ZipArchive(memoryStream , ZipArchiveMode.Create))
{
    var demoFile = archive.CreateEntry("foo.txt");

    using (var entryStream = demoFile.Open())
    using (var streamWriter = new StreamWriter(entryStream))
    {
        streamWriter.Write("Bar!");
    }

    using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
    {
        stream.CopyTo(fileStream);
    }
}

如果我运行此代码,则会创建存档文件本身,但不会创建 foo.txt

但是,如果我直接将MemoryStream 替换为文件流,则会正确创建存档:

using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
using (var archive = new ZipArchive(fileStream, FileMode.Create))
{
    // ...
}

是否可以使用MemoryStream 来创建没有FileStream 的ZIP 存档?

【问题讨论】:

标签: c# .net zip compression ziparchive


【解决方案1】:

我迟到了,但在某些情况下,您无法访问 ZipArchive 的构造函数来设置 leaveOpen 参数,并且您不希望将 ZIP 写入磁盘。就我而言,我在内部使用的 AsiceArchive 类创建了一个 ZipArchive,但没有将 leaveOpen 设置为 true。

我创建了Stream 的一个子类,它将所有调用委托给一个内部流(使用 ReSharper 单击几下)。这个类不是一次性的,所以当ZipArchive 被释放时,内部流不会发生任何事情。

public class NondisposingStreamWrapper : Stream
{
    private readonly Stream _streamImplementation;

    public NondisposingStreamWrapper(Stream inner) => _streamImplementation = inner;

    public override void Flush() => _streamImplementation.Flush();

    public override int Read(byte[] buffer, int offset, int count) => _streamImplementation.Read(buffer, offset, count);

    public override long Seek(long offset, SeekOrigin origin) => _streamImplementation.Seek(offset, origin);

    public override void SetLength(long value) => _streamImplementation.SetLength(value);

    public override void Write(byte[] buffer, int offset, int count) => _streamImplementation.Write(buffer, offset, count);

    public override bool CanRead => _streamImplementation.CanRead;

    public override bool CanSeek => _streamImplementation.CanSeek;

    public override bool CanWrite => _streamImplementation.CanWrite;

    public override long Length => _streamImplementation.Length;

    public override long Position
    {
        get => _streamImplementation.Position;
        set => _streamImplementation.Position = value;
    }
}

像这样使用它:

using var memoryStream = new MemoryStream();
var output = new NondisposingStreamWrapper(memoryStream);

using (var archive = new ZipArchive(output, ZipArchiveMode.Create))
{
    // add entries to archive
}

memoryStream.Flush();
memoryStream.Position = 0;

// write to file just for testing purposes
File.WriteAllBytes("out.zip", memoryStream.ToArray());

【讨论】:

    【解决方案2】:

    感谢ZipArchive creates invalid ZIP file,我得到了:

    using (var memoryStream = new MemoryStream())
    {
       using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
       {
          var demoFile = archive.CreateEntry("foo.txt");
    
          using (var entryStream = demoFile.Open())
          using (var streamWriter = new StreamWriter(entryStream))
          {
             streamWriter.Write("Bar!");
          }
       }
    
       using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
       {
          memoryStream.Seek(0, SeekOrigin.Begin);
          memoryStream.CopyTo(fileStream);
       }
    }
    

    这表明我们需要在 ZipArchive 上调用 Dispose 才能使用它,正如 Amir 所暗示的那样,这很可能是因为它会将最终字节(如校验和)写入使其完整的存档。但是为了不关闭流,以便我们可以在您需要将true 作为第三个参数传递给ZipArchive 之后重新使用它。

    【讨论】:

      【解决方案3】:

      以防万一,如果有人想通过 SaveFileDialog 保存动态 zip 文件。

              var logFileName = "zip_filename.zip";
              appLogSaver.FileName = logFileName;
              appLogSaver.Filter = "LogFiles|*.zip";
              appLogSaver.DefaultExt = "zip";
              DialogResult resDialog = appLogSaver.ShowDialog();
      
              if (resDialog.ToString() == "OK")
              {
                  System.IO.FileStream fs = (System.IO.FileStream)appLogSaver.OpenFile();
      
                  using (var memoryStream = new MemoryStream())
                  {
                      using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
                      {
                          var demoFile = archive.CreateEntry("foo.txt");
                          using (var entryStream = demoFile.Open())
                          {
                              using (var streamWriter = new StreamWriter(entryStream))
                              {
                                  //read your existing file and put the content here 
                                  streamWriter.Write("Bar!");
                              }
                          }
      
                          var demoFile2 = archive.CreateEntry("foo2.txt");
                          using (var entryStream = demoFile2.Open())
                          {
                              using (var streamWriter = new StreamWriter(entryStream))
                              {
                                  streamWriter.Write("Bar2!");
                              }
                          }
                      }
      
                      memoryStream.Seek(0, SeekOrigin.Begin);
                      memoryStream.CopyTo(fs);
                  }
                  fs.Close();
              }
      

      【讨论】:

        【解决方案4】:

        返回包含 zip 文件的流的函数

        public static Stream ZipGenerator(List<string> files)
            {
                ZipArchiveEntry fileInArchive;
                Stream entryStream;
                int i = 0;
                List<byte[]> byteArray = new List<byte[]>();
        
                foreach (var file in files)
                {
                    byteArray.Add(File.ReadAllBytes(file));
                }
        
                var outStream = new MemoryStream();
        
                using (var archive = new ZipArchive(outStream, ZipArchiveMode.Create, true))
                {
                    foreach (var file in files)
                    {
                        fileInArchive=(archive.CreateEntry(Path.GetFileName(file), CompressionLevel.Optimal));
        
                        using (entryStream = fileInArchive.Open())
                        {
                                using (var fileToCompressStream = new MemoryStream(byteArray[i]))
                                {
                                    fileToCompressStream.CopyTo(entryStream);
                                }
                                i++;
                        }
                    }
                }
                outStream.Position = 0;
                return outStream;
            }
        

        如果需要,将 zip 写入文件流。

        using (var fileStream = new FileStream(@"D:\Tools\DBExtractor\DBExtractor\bin\Debug\test.zip", FileMode.Create))
        {
           outStream.Position = 0;
           outStream.WriteTo(fileStream);
        }
        

        `

        【讨论】:

        • 先将所有文件读入内存是极大的内存浪费。您最终会在内存中两次获得所有文件。一次在byteArray 和一次在ZipArchive。更不用说您根本不需要将文件加载到内存中。使用流式传输,如所有其他现有答案所示。
        • @MartinPrikryl 问题是将 zip 文件写入内存的方法。这就是我使用内存的原因。当然最好的方法是写入本地
        • 我知道问题是关于什么的。我的评论的重点是,您在内存中创建 ZIP 文件的实现非常低效。其他答案中的实现更好。
        【解决方案5】:

        MVC 的工作解决方案

            public ActionResult Index()
            {
                string fileName = "test.pdf";
                string fileName1 = "test.vsix";
                string fileNameZip = "Export_" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".zip";
        
                byte[] fileBytes = System.IO.File.ReadAllBytes(@"C:\test\test.pdf");
                byte[] fileBytes1 = System.IO.File.ReadAllBytes(@"C:\test\test.vsix");
                byte[] compressedBytes;
                using (var outStream = new MemoryStream())
                {
                    using (var archive = new ZipArchive(outStream, ZipArchiveMode.Create, true))
                    {
                        var fileInArchive = archive.CreateEntry(fileName, CompressionLevel.Optimal);
                        using (var entryStream = fileInArchive.Open())
                        using (var fileToCompressStream = new MemoryStream(fileBytes))
                        {
                            fileToCompressStream.CopyTo(entryStream);
                        }
        
                        var fileInArchive1 = archive.CreateEntry(fileName1, CompressionLevel.Optimal);
                        using (var entryStream = fileInArchive1.Open())
                        using (var fileToCompressStream = new MemoryStream(fileBytes1))
                        {
                            fileToCompressStream.CopyTo(entryStream);
                        }
        
        
                    }
                    compressedBytes = outStream.ToArray();
                }
                return File(compressedBytes, "application/zip", fileNameZip);
            }
        

        【讨论】:

        • Controller.File method has an overload that accepts Stream。使用它来避免在内存中创建另一个 ZIP 文件副本。
        • 天哪,这是谷歌搜索一个小时后的第一个直接答案。谢谢!
        • 这个解决方案完美!谢谢!您甚至不需要移动字节数组 (byte[])。只需使用 MemoryStream 并且不要忘记在返回结果之前寻找零 (.Seek(0, SeekOrigin.Begin);)
        • 可以在 donet core 5.* w/WebApi 中确认这对我有用。
        【解决方案6】:

        只是另一个版本的压缩而不写入任何文件。

        string fileName = "export_" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".xlsx";
        byte[] fileBytes = here is your file in bytes
        byte[] compressedBytes;
        string fileNameZip = "Export_" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".zip";
        
        using (var outStream = new MemoryStream())
        {
            using (var archive = new ZipArchive(outStream, ZipArchiveMode.Create, true))
            {
                var fileInArchive = archive.CreateEntry(fileName, CompressionLevel.Optimal);
                using (var entryStream = fileInArchive.Open())
                using (var fileToCompressStream = new MemoryStream(fileBytes))
                {
                    fileToCompressStream.CopyTo(entryStream);
                }
            }
            compressedBytes = outStream.ToArray();
        }
        

        【讨论】:

          【解决方案7】:
          using System;
          using System.IO;
          using System.IO.Compression;
          
          namespace ConsoleApplication
          {
              class Program`enter code here`
              {
                  static void Main(string[] args)
                  {
                      using (FileStream zipToOpen = new FileStream(@"c:\users\exampleuser\release.zip", FileMode.Open))
                      {
                          using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
                          {
                              ZipArchiveEntry readmeEntry = archive.CreateEntry("Readme.txt");
                              using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
                              {
                                      writer.WriteLine("Information about this package.");
                                      writer.WriteLine("========================");
                              }
                          }
                      }
                  }
              }
          }
          

          【讨论】:

            【解决方案8】:

            这是将实体转换为 XML 文件然后对其进行压缩的方法:

            private  void downloadFile(EntityXML xml) {
            
            string nameDownloadXml = "File_1.xml";
            string nameDownloadZip = "File_1.zip";
            
            var serializer = new XmlSerializer(typeof(EntityXML));
            
            Response.Clear();
            Response.ClearContent();
            Response.ClearHeaders();
            Response.AddHeader("content-disposition", "attachment;filename=" + nameDownloadZip);
            
            using (var memoryStream = new MemoryStream())
            {
                using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
                {
                    var demoFile = archive.CreateEntry(nameDownloadXml);
                    using (var entryStream = demoFile.Open())
                    using (StreamWriter writer = new StreamWriter(entryStream, System.Text.Encoding.UTF8))
                    {
                        serializer.Serialize(writer, xml);
                    }
                }
            
                using (var fileStream = Response.OutputStream)
                {
                    memoryStream.Seek(0, SeekOrigin.Begin);
                    memoryStream.CopyTo(fileStream);
                }
            }
            
            Response.End();
            

            }

            【讨论】:

              【解决方案9】:
                     private void button6_Click(object sender, EventArgs e)
                  {
              
                      //create With Input FileNames
                      AddFileToArchive_InputByte(new ZipItem[]{ new ZipItem( @"E:\b\1.jpg",@"images\1.jpg"),
                          new ZipItem(@"E:\b\2.txt",@"text\2.txt")}, @"C:\test.zip");
              
                      //create with input stream
                      AddFileToArchive_InputByte(new ZipItem[]{ new ZipItem(File.ReadAllBytes( @"E:\b\1.jpg"),@"images\1.jpg"),
                          new ZipItem(File.ReadAllBytes(@"E:\b\2.txt"),@"text\2.txt")}, @"C:\test.zip");
              
                      //Create Archive And Return StreamZipFile
                      MemoryStream GetStreamZipFile = AddFileToArchive(new ZipItem[]{ new ZipItem( @"E:\b\1.jpg",@"images\1.jpg"),
                          new ZipItem(@"E:\b\2.txt",@"text\2.txt")});
              
              
                      //Extract in memory
                      ZipItem[] ListitemsWithBytes = ExtractItems(@"C:\test.zip");
              
                      //Choese Files For Extract To memory
                      List<string> ListFileNameForExtract = new List<string>(new string[] { @"images\1.jpg", @"text\2.txt" });
                      ListitemsWithBytes = ExtractItems(@"C:\test.zip", ListFileNameForExtract);
              
              
                      // Choese Files For Extract To Directory
                      ExtractItems(@"C:\test.zip", ListFileNameForExtract, "c:\\extractFiles");
              
                  }
              
                  public struct ZipItem
                  {
                      string _FileNameSource;
                      string _PathinArchive;
                      byte[] _Bytes;
                      public ZipItem(string __FileNameSource, string __PathinArchive)
                      {
                          _Bytes=null ;
                          _FileNameSource = __FileNameSource;
                          _PathinArchive = __PathinArchive;
                      }
                      public ZipItem(byte[] __Bytes, string __PathinArchive)
                      {
                          _Bytes = __Bytes;
                          _FileNameSource = "";
                          _PathinArchive = __PathinArchive;
              
                      }
                      public string FileNameSource
                      {
                          set
                          {
                              FileNameSource = value;
                          }
                          get
                          {
                              return _FileNameSource;
                          }
                      }
                      public string PathinArchive
                      {
                          set
                          {
                              _PathinArchive = value;
                          }
                          get
                          {
                              return _PathinArchive;
                          }
                      }
                      public byte[] Bytes
                      {
                          set
                          {
                              _Bytes = value;
                          }
                          get
                          {
                              return _Bytes;
                          }
                      }
                  }
              
              
                   public void AddFileToArchive(ZipItem[] ZipItems, string SeveToFile)
                  {
              
                      MemoryStream memoryStream = new MemoryStream();
              
                      //Create Empty Archive
                      ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true);
              
                      foreach (ZipItem item in ZipItems)
                      {
              
                          //Create Path File in Archive
                          ZipArchiveEntry FileInArchive = archive.CreateEntry(item.PathinArchive);
              
              
                          //Open File in Archive For Write
                          var OpenFileInArchive = FileInArchive.Open();
              
                          //Read Stream
                          FileStream fsReader = new FileStream(item.FileNameSource, FileMode.Open, FileAccess.Read);
              
                          byte[] ReadAllbytes = new byte[4096];//Capcity buffer
                          int ReadByte = 0;
                          while (fsReader.Position != fsReader.Length)
                          {
                              //Read Bytes
                              ReadByte = fsReader.Read(ReadAllbytes, 0, ReadAllbytes.Length);
              
                              //Write Bytes
                              OpenFileInArchive.Write(ReadAllbytes, 0, ReadByte);
                          }
                          fsReader.Dispose();
                          OpenFileInArchive.Close();
              
              
                      }
                      archive.Dispose();
              
                      using (var fileStream = new FileStream(SeveToFile, FileMode.Create))
                      {
                          memoryStream.Seek(0, SeekOrigin.Begin);
                          memoryStream.CopyTo(fileStream);
                      }
              
              
              
              
              
                  }
                   public MemoryStream  AddFileToArchive(ZipItem[] ZipItems)
                  {
              
                      MemoryStream memoryStream = new MemoryStream();
              
                      //Create Empty Archive
                      ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true);
              
                      foreach (ZipItem item in ZipItems)
                      {
              
                          //Create Path File in Archive
                          ZipArchiveEntry FileInArchive = archive.CreateEntry(item.PathinArchive);
              
              
                          //Open File in Archive For Write
                          var OpenFileInArchive = FileInArchive.Open();
              
                          //Read Stream
                          FileStream fsReader = new FileStream(item.FileNameSource, FileMode.Open, FileAccess.Read);
              
                          byte[] ReadAllbytes = new byte[4096];//Capcity buffer
                          int ReadByte = 0;
                          while (fsReader.Position != fsReader.Length)
                          {
                              //Read Bytes
                              ReadByte = fsReader.Read(ReadAllbytes, 0, ReadAllbytes.Length);
              
                              //Write Bytes
                              OpenFileInArchive.Write(ReadAllbytes, 0, ReadByte);
                          }
                          fsReader.Dispose();
                          OpenFileInArchive.Close();
              
              
                      }
                      archive.Dispose();
              
              
              
              
                      return memoryStream;
              
              
                  }
              
                   public void AddFileToArchive_InputByte(ZipItem[] ZipItems, string SeveToFile)
                  {
              
                      MemoryStream memoryStream = new MemoryStream();
              
                      //Create Empty Archive
                      ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true);
              
                      foreach (ZipItem item in ZipItems)
                      {
              
                          //Create Path File in Archive
                          ZipArchiveEntry FileInArchive = archive.CreateEntry(item.PathinArchive);
              
              
                          //Open File in Archive For Write
                          var OpenFileInArchive = FileInArchive.Open();
              
                          //Read Stream
                        //  FileStream fsReader = new FileStream(item.FileNameSource, FileMode.Open, FileAccess.Read);
              
                          byte[] ReadAllbytes = new byte[4096];//Capcity buffer
                          int ReadByte = 4096 ;int  TotalWrite=0;
                          while (TotalWrite != item.Bytes.Length)
                          {
              
                              if(TotalWrite+4096>item.Bytes.Length)
                               ReadByte=item.Bytes.Length-TotalWrite;
              
              
              
                              Array.Copy(item.Bytes, TotalWrite, ReadAllbytes, 0, ReadByte);
              
              
              
              
                              //Write Bytes
                              OpenFileInArchive.Write(ReadAllbytes, 0, ReadByte);
                              TotalWrite += ReadByte;
                          }
              
                          OpenFileInArchive.Close();
              
              
                      }
                      archive.Dispose();
              
                      using (var fileStream = new FileStream(SeveToFile, FileMode.Create))
                      {
                          memoryStream.Seek(0, SeekOrigin.Begin);
                          memoryStream.CopyTo(fileStream);
                      }
              
              
                  }
                   public MemoryStream  AddFileToArchive_InputByte(ZipItem[] ZipItems)
                  {
              
                      MemoryStream memoryStream = new MemoryStream();
              
                      //Create Empty Archive
                      ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true);
              
                      foreach (ZipItem item in ZipItems)
                      {
              
                          //Create Path File in Archive
                          ZipArchiveEntry FileInArchive = archive.CreateEntry(item.PathinArchive);
              
              
                          //Open File in Archive For Write
                          var OpenFileInArchive = FileInArchive.Open();
              
                          //Read Stream
                        //  FileStream fsReader = new FileStream(item.FileNameSource, FileMode.Open, FileAccess.Read);
              
                          byte[] ReadAllbytes = new byte[4096];//Capcity buffer
                          int ReadByte = 4096 ;int  TotalWrite=0;
                          while (TotalWrite != item.Bytes.Length)
                          {
              
                              if(TotalWrite+4096>item.Bytes.Length)
                               ReadByte=item.Bytes.Length-TotalWrite;
              
              
              
                              Array.Copy(item.Bytes, TotalWrite, ReadAllbytes, 0, ReadByte);
              
              
              
              
                              //Write Bytes
                              OpenFileInArchive.Write(ReadAllbytes, 0, ReadByte);
                              TotalWrite += ReadByte;
                          }
              
                          OpenFileInArchive.Close();
              
              
                      }
                      archive.Dispose();
              
              
              
                      return memoryStream;
                  }
              
                   public void ExtractToDirectory(string sourceArchiveFileName, string destinationDirectoryName)
                   {
                       //Opens the zip file up to be read
                       using (ZipArchive archive = ZipFile.OpenRead(sourceArchiveFileName))
                       {
                           if (Directory.Exists(destinationDirectoryName)==false )
                               Directory.CreateDirectory(destinationDirectoryName);
              
                           //Loops through each file in the zip file
                           archive.ExtractToDirectory(destinationDirectoryName);
              
                       }
                   }  
                   public void   ExtractItems(string sourceArchiveFileName,List< string> _PathFilesinArchive, string destinationDirectoryName)
                   {
              
                       //Opens the zip file up to be read
                       using (ZipArchive archive = ZipFile.OpenRead(sourceArchiveFileName))
                       {
              
              
                           //Loops through each file in the zip file
                           foreach (ZipArchiveEntry file in archive.Entries)
                           {
                               int PosResult = _PathFilesinArchive.IndexOf(file.FullName);
                               if (PosResult != -1)
                               {
                                   //Create Folder
                                   if (Directory.Exists( destinationDirectoryName + "\\" +Path.GetDirectoryName( _PathFilesinArchive[PosResult])) == false)
                                       Directory.CreateDirectory(destinationDirectoryName + "\\" + Path.GetDirectoryName(_PathFilesinArchive[PosResult]));
              
                                   Stream OpenFileGetBytes = file.Open();
              
                                   FileStream   FileStreamOutput = new FileStream(destinationDirectoryName + "\\" + _PathFilesinArchive[PosResult], FileMode.Create);
              
                                   byte[] ReadAllbytes = new byte[4096];//Capcity buffer
                                   int ReadByte = 0; int TotalRead = 0; 
                                   while (TotalRead != file.Length)
                                   {
                                       //Read Bytes
                                       ReadByte = OpenFileGetBytes.Read(ReadAllbytes, 0, ReadAllbytes.Length);
                                       TotalRead += ReadByte;
              
                                       //Write Bytes
                                       FileStreamOutput.Write(ReadAllbytes, 0, ReadByte);
                                   }
              
                                   FileStreamOutput.Close();
                                   OpenFileGetBytes.Close();
              
              
              
                                   _PathFilesinArchive.RemoveAt(PosResult);
                               }
              
                               if (_PathFilesinArchive.Count == 0)
                                   break;
                           }
                       }
              
              
                   }
              
                   public ZipItem[] ExtractItems(string sourceArchiveFileName)
                   {
                     List<  ZipItem> ZipItemsReading = new List<ZipItem>();
                       //Opens the zip file up to be read
                       using (ZipArchive archive = ZipFile.OpenRead(sourceArchiveFileName))
                       {
              
              
                           //Loops through each file in the zip file
                           foreach (ZipArchiveEntry file in archive.Entries)
                           {
                               Stream OpenFileGetBytes = file.Open();
              
                               MemoryStream memstreams = new MemoryStream();
                               byte[] ReadAllbytes = new byte[4096];//Capcity buffer
                               int ReadByte = 0; int TotalRead = 0;
                               while (TotalRead != file.Length)
                               {
                                   //Read Bytes
                                   ReadByte = OpenFileGetBytes.Read(ReadAllbytes, 0, ReadAllbytes.Length);
                                   TotalRead += ReadByte;
              
                                   //Write Bytes
                                   memstreams.Write(ReadAllbytes, 0, ReadByte);
                               }
              
                               memstreams.Position = 0;
                               OpenFileGetBytes.Close();
                               memstreams.Dispose();
              
                               ZipItemsReading.Add(new ZipItem(memstreams.ToArray(),file.FullName));
              
              
                           }
                       }
              
                       return ZipItemsReading.ToArray();
                   }
                   public ZipItem[] ExtractItems(string sourceArchiveFileName,List< string> _PathFilesinArchive)
                   {
                     List<  ZipItem> ZipItemsReading = new List<ZipItem>();
                       //Opens the zip file up to be read
                       using (ZipArchive archive = ZipFile.OpenRead(sourceArchiveFileName))
                       {
              
                           //Loops through each file in the zip file
                           foreach (ZipArchiveEntry file in archive.Entries)
                           {
                               int PosResult = _PathFilesinArchive.IndexOf(file.FullName); 
                               if (PosResult!= -1)
                               {
                                   Stream OpenFileGetBytes = file.Open();
              
                                   MemoryStream memstreams = new MemoryStream();
                                   byte[] ReadAllbytes = new byte[4096];//Capcity buffer
                                   int ReadByte = 0; int TotalRead = 0;  
                                   while (TotalRead != file.Length)
                                   {
                                       //Read Bytes
                                       ReadByte = OpenFileGetBytes.Read(ReadAllbytes, 0, ReadAllbytes.Length);
                                       TotalRead += ReadByte;
              
                                       //Write Bytes
                                       memstreams.Write(ReadAllbytes, 0, ReadByte);
                                   }
              
                                   //Create item
                                   ZipItemsReading.Add(new ZipItem(memstreams.ToArray(),file.FullName));
              
                                   OpenFileGetBytes.Close();
                                   memstreams.Dispose();
              
              
              
                                   _PathFilesinArchive.RemoveAt(PosResult);
                               }
              
                               if (_PathFilesinArchive.Count == 0)
                                   break;
              
              
                           }
                       }
              
                       return ZipItemsReading.ToArray();
                   }
              

              【讨论】:

                【解决方案10】:

                将流的位置设置为 0,然后再将其复制到 zip 流。

                using (var memoryStream = new MemoryStream())
                {
                 using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
                 {
                  var demoFile = archive.CreateEntry("foo.txt");
                
                  using (var entryStream = demoFile.Open())
                  using (var streamWriter = new StreamWriter(entryStream))
                  {
                     streamWriter.Write("Bar!");
                  }
                 }
                
                 using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
                   {
                     memoryStream.Position=0;
                     memoryStream.WriteTo(fileStream);
                   }
                 }
                

                【讨论】:

                • 感谢您提供直接的解决方案。赞!!
                【解决方案11】:

                你需要写完内存流然后读回缓冲区。

                        using (var memoryStream = new MemoryStream())
                        {
                            using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create))
                            {
                                var demoFile = archive.CreateEntry("foo.txt");
                
                                using (var entryStream = demoFile.Open())
                                using (var streamWriter = new StreamWriter(entryStream))
                                {
                                    streamWriter.Write("Bar!");
                                }
                            }
                
                            using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
                            {
                                var bytes = memoryStream.GetBuffer();
                                fileStream.Write(bytes,0,bytes.Length );
                            }
                        }
                

                【讨论】:

                  猜你喜欢
                  • 2019-04-02
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2022-06-24
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多