Marius Schulz Marius Schulz - 3 months ago 212
C# Question

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

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

Thanks to http://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.