13

My problem is that as soon as ZipArchive is disposed, it automatically closes and disposes the MemoryStream. If I look at the stream before the disposal of ZipArchive the information is not well formed zip.

using (var compressStream = new MemoryStream())
{
    using (var zipArchive = new ZipArchive(compressStream, ZipArchiveMode.Create))
    {
        // Adding a couple of entries
        string navStackInfo = Navigation.NavState.CurrentStackInfoLines();
        var navStackEntry = zipArchive.CreateEntry("NavStack.txt", CompressionLevel.NoCompression);
        using (StreamWriter writer = new StreamWriter(navStackEntry.Open()))
        {
             writer.Write(navStackInfo);
        }
        var debugInfoEntry = zipArchive.CreateEntry("CallStack.txt", CompressionLevel.Optimal);
        using (StreamWriter writer = new StreamWriter(debugInfoEntry.Open()))
        {
            // debugInfo.Details is a string too
            writer.Write(debugInfo.Details);
        }
        // ...
        // compressStream here is not well formed
    }
    // compressStream here is closed and disposed
}

So how should this work? Maybe the only problem is that it's not well formed? I see "PK" header number within the file (not just at the beginning) at the beginning of each entry part. I'm not sure if that's good or not. Certainly if I save the stream to a file I cannot open it as a zip file, something is wrong. (In the final code I do not want to materialize a file in a crash handling code though.)

Csaba Toth
  • 10,021
  • 5
  • 75
  • 121
  • It looks like you have an extra bracket after the writer.Write(navStackInfo); that closes the zipArchive. – DavidN Feb 12 '14 at 19:38
  • @DavidN Thanks, that was just there, because in my real code there are extra null pointer checks and stuff, so I simplified this example. – Csaba Toth Feb 12 '14 at 21:06
  • BTW, if I say `using (var zipArchive = ZipFile.Open(@"wtf.zip", ZipArchiveMode.Create)`, the resulting physical zip file is a well formed, and significantly larger (50KB vs 10KB) than what I see in the Stream version. So either the stuff is not flushed out from `ZipArchive` into the stream and/or the stream is not flushed. I tried to flush the stream, but it didn't help. – Csaba Toth Feb 13 '14 at 17:59
  • Maybe should be considered dup of http://stackoverflow.com/q/12347775/1178314 which moreover has currently a better accepted answer. – Frédéric May 15 '15 at 10:34
  • I modified the correct answer here to the leaveOpen one also. – Csaba Toth May 15 '15 at 17:43

1 Answers1

23

I just ran into the same issue, and I noticed that there's an optional parameter for the ZipArchive constructor called leaveOpen. Documentation says: True to leave the stream open after the System.IO.Compression.ZipArchive object is disposed; otherwise, false.

This solved the problem for me.

Jeremy
  • 1,021
  • 9
  • 8
  • Good to know. I guess it's some new thing, or all of us overlooked it. There was development going on in that ZipArchive area. Thanks for letting us know. – Csaba Toth Mar 03 '15 at 20:20
  • Now that .NET is on GitHub I tried to find it, but no luck yet https://github.com/dotnet/coreclr/search?q=ziparchive https://github.com/dotnet/corefx/search?q=ziparchive – Csaba Toth Mar 03 '15 at 20:23
  • Link for the constructor overload doc on msdn: https://msdn.microsoft.com/en-us/library/hh137431(v=vs.110).aspx – Frédéric May 15 '15 at 10:30