Creating a ZIP Archive in Memory Using System.IO.Compression

Marius Schulz picture Marius Schulz · Jun 21, 2013 · Viewed 183k times · Source

I'm trying to create a ZIP archive with a simple demo text file using a MemoryStream as follows:

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

If I run this code, the archive file itself is created but foo.txt isn't.

However, if I replace the MemoryStream directly with the file stream, the archive is created correctly:

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

Is it possible to use a MemoryStream to create the ZIP archive without the FileStream?

Answer

Michael picture Michael · Jul 30, 2013

Thanks to https://stackoverflow.com/a/12350106/222748 I got:

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

So we need to call dispose on ZipArchive before we can use it, which means passing 'true' as the third parameter to the ZipArchive so we can still access the stream after disposing it.