[
  {
    "Id": "286736",
    "ThreadId": "83395",
    "Html": "<p>I created a ZipOutputStream with a MemoryStream as its underlying store (for the purpose of signing the zipfile when it's completed). I did some tests with just adding stuff to the file and then writing it to disk, and I'm seeing corrupted headers. Either I'm doing this horribly wrong or I have found a breaking use case.</p>\r\n<p>Here's a bit of sample code that demonstrates the problem:</p>\r\n<p>\r\n<div style=\"color:Black;background-color:White\">\r\n<pre>MemoryStream memStream = <span style=\"color:Blue\">new</span> MemoryStream();\r\nmZipData = <span style=\"color:Blue\">new</span> ZipOutputStream(memStream);\r\n\r\nmZipData.PutNextEntry(<span style=\"color:#A31515\">&quot;foo.txt&quot;</span>);\r\n<span style=\"color:Blue\">byte</span>[] buffer = System.Text.Encoding.ASCII.GetBytes(<span style=\"color:#A31515\">&quot;This is a file called foo.txt&quot;</span>);\r\nmZipData.Write(buffer, 0, buffer.Length);\r\n\r\nmZipData.PutNextEntry(<span style=\"color:#A31515\">@&quot;subdir/&quot;</span>);\r\n\r\nmZipData.PutNextEntry(<span style=\"color:#A31515\">@&quot;subdir/bar.txt&quot;</span>);\r\nbuffer = System.Text.Encoding.ASCII.GetBytes(<span style=\"color:#A31515\">&quot;This is another file, called bar.txt, &quot;</span> +\r\n    <span style=\"color:#A31515\">&quot;which lives in the subdirectory 'subdir'&quot;</span>);\r\nmZipData.Write(buffer, 0, buffer.Length);\r\n\r\nFileStream outStream = <span style=\"color:Blue\">new</span> FileStream(<span style=\"color:#A31515\">@&quot;.\\test.zip&quot;</span>, FileMode.Create, FileAccess.Write);\r\nmemStream.Seek(0, 0);\r\nmemStream.WriteTo(outStream);\r\n</pre>\r\n</div>\r\n</p>\r\n<p>I think what might be happening is that under normal circumstances, the ZipOutputStream gets Disposed when it goes out of scope. This calls _FinishCurrentEntry, which on cursory examination looks like it then flushes the header and the entry contents. Since I'm directly accessing the underlying stream before anything has triggered _FinishCurrentEntry, the end of the archive is left in an unclean state. The corrupted result appears to only have the foo.txt entry. It's also possible I'm not doing the right thing with the subdirectory there...</p>\r\n<p>Tim Keating</p>\r\n<p>&nbsp;</p>",
    "PostedDate": "2010-02-06T22:00:42.177-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "286896",
    "ThreadId": "83395",
    "Html": "<p>Hi Tim,</p>\r\n<p>you're doing the correct thing with the directory.&nbsp;</p>\r\n<p>The problem is, yes, the ZipOutputStream is not being Disposed.&nbsp; Your output stream is not a complete zip file, until you Dispose the object.&nbsp;</p>\r\n<p>You use the words &quot;under normal circumstances, the ZipOutputStream gets Disposed when it goes out of scope&quot;.&nbsp; This is not correct usage, and your expectation is also not correct.&nbsp; The Dispose() is not optional.&nbsp; You must Dispose the object in order for it to work properly, as documented.&nbsp; &nbsp; There's no way around that.&nbsp;&nbsp; If you let the object drift out of scope, there is no guarantee that it will work as you want it to.&nbsp; Call Dispose().</p>\r\n<p>If there is any example in the DotNetZip documentation that does not show correct usage of the Dispose() method with ZipOutputStream, or the using clause, which is equivalent, then please let me know.&nbsp; If there is any statement in the doc that seems to indicate that Dispose() is not necessary, let me know.</p>\r\n<p>Here's the example of using ZipOutputStream with a memory stream:</p>\r\n<div style=\"color:Black;background-color:White\">\r\n<pre>   <span style=\"color:Blue\">using</span> (MemoryStream ms = <span style=\"color:Blue\">new</span> MemoryStream())\r\n    {\r\n        <span style=\"color:Blue\">using</span> (<span style=\"color:Blue\">var</span> output= <span style=\"color:Blue\">new</span> ZipOutputStream(ms))\r\n        {\r\n            output.Password = <span style=\"color:#A31515\">&quot;VerySecret!&quot;</span>;\r\n            output.Encryption = EncryptionAlgorithm.WinZipAes256;\r\n            output.PutNextEntry(<span style=\"color:#A31515\">&quot;entry1.txt&quot;</span>);\r\n            <span style=\"color:Blue\">byte</span>[] buffer= System.Text.Encoding.ASCII.GetBytes(<span style=\"color:#A31515\">&quot;This is the content for entry #1.&quot;</span>);\r\n            output.Write(buffer,0,buffer.Length);\r\n            output.PutNextEntry(<span style=\"color:#A31515\">&quot;entry2.txt&quot;</span>);  <span style=\"color:Green\">// this will be zero length</span>\r\n            output.PutNextEntry(<span style=\"color:#A31515\">&quot;entry3.txt&quot;</span>);\r\n            buffer= System.Text.Encoding.ASCII.GetBytes(<span style=\"color:#A31515\">&quot;This is the content for entry #3.&quot;</span>);\r\n            output.Write(buffer,0,buffer.Length);\r\n        }\r\n\r\n        <span style=\"color:Green\">// ms now contains the complete bytes for a zip file</span>\r\n    }\r\n\r\n</pre>\r\n</div>",
    "PostedDate": "2010-02-07T14:52:28.793-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "286949",
    "ThreadId": "83395",
    "Html": "<p>Aha! I saw the FileStream example under the PutNextEntry documentation, which I presume this is based on. However, my previous .Net experience goes back to 2.0, and I completely missed the significance of the<span style=\"color:Blue\"> </span>using blocks.</p>\r\n<p>It might be worth explicitly calling out the need to Dispose the ZipOutputStream object in the overview. Short of that, though, this one's all on me.</p>\r\n<p>TK</p>",
    "PostedDate": "2010-02-07T20:18:08.437-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "286950",
    "ThreadId": "83395",
    "Html": "<p>Hmm, I actually figured this out not too long after posting this last night, and replied with a follow-up. I wonder where the heck that post went?</p>\r\n<p>In any case, for posterity, here is the code I used to replace the last three lines, which made it work:</p>\r\n<p>\r\n<div style=\"color:Black;background-color:White\">\r\n<pre>mZipData.Close();\r\nFileStream outStream = <span style=\"color:Blue\">new</span> FileStream(<span style=\"color:#A31515\">@&quot;.\\test.zip&quot;</span>, FileMode.Create, FileAccess.Write);\r\nBinaryWriter writer = <span style=\"color:Blue\">new</span> BinaryWriter(outStream);\r\nwriter.Write(mMemStream.GetBuffer());\r\n</pre>\r\n</div>\r\n</p>",
    "PostedDate": "2010-02-07T20:19:55.423-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "287766",
    "ThreadId": "83395",
    "Html": "<p>Ok, thanks for the tip; I will update the documentation to make this more explicit.</p>",
    "PostedDate": "2010-02-09T11:36:16.407-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  }
]