[
  {
    "Id": "638918",
    "ThreadId": "264298",
    "Html": "\r\n<p>Im not sure what the source of this problem is. I made a class derived from Stream which just acts as one Stream but writes to a FileStream and a NetworkStream in one shot. The problem is when the zipping comes accross a file that is either in use or does\r\n not exists, it fires the ZipError event but then throws an exception for the same file, even though I set the ZipErrorAction to Skip. If I do not use the MultiWriteStream and leave the rest of the code the same this problem does not occur. Here is a simplified\r\n version of my code which causes the problem:</p>\r\n<p></p>\r\n<div style=\"color:black; background-color:white\">\r\n<pre><span style=\"color:blue\">public</span> <span style=\"color:blue\">class</span> Program\r\n{\r\n    <span style=\"color:blue\">static</span> <span style=\"color:blue\">void</span> Main()\r\n    {\r\n        Socket socket = <span style=\"color:blue\">new</span> Socket(AddressFamily.InterNetwork, \r\n            SocketType.Stream, ProtocolType.Tcp);\r\n        socket.Connect(<span style=\"color:#a31515\">&quot;localhost&quot;</span>, 1500);\r\n        <span style=\"color:blue\">using</span> (<span style=\"color:blue\">var</span> ns = <span style=\"color:blue\">new</span> NetworkStream(socket))\r\n        {\r\n            <span style=\"color:blue\">using</span> (<span style=\"color:blue\">var</span> fs = File.Create(<span style=\"color:#a31515\">&quot;C:\\\\test.zip&quot;</span>))\r\n            {\r\n                <span style=\"color:blue\">using</span> (<span style=\"color:blue\">var</span> zip = <span style=\"color:blue\">new</span> ZipFile())\r\n                {\r\n                    zip.ZipError &#43;= ZipError;\r\n                    zip.AddFile(<span style=\"color:#a31515\">&quot;C:\\\\FileInUse.txt&quot;</span>);\r\n                    <span style=\"color:blue\">using</span> (<span style=\"color:blue\">var</span> stream = <span style=\"color:blue\">new</span> MultiWriteStream(ns, fs))\r\n                    {\r\n                        zip.Save(stream);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    <span style=\"color:blue\">public</span> <span style=\"color:blue\">static</span> <span style=\"color:blue\">void</span> ZipError(<span style=\"color:blue\">object</span> sender, ZipErrorEventArgs e)\r\n    {\r\n        e.CurrentEntry.ZipErrorAction = ZipErrorAction.Skip;\r\n    }\r\n}\r\n<span style=\"color:blue\">public</span> <span style=\"color:blue\">class</span> MultiWriteStream : Stream\r\n{\r\n    NetworkStream netStream;\r\n    FileStream fileStream;\r\n\r\n    <span style=\"color:blue\">public</span> MultiWriteStream(NetworkStream netStream, FileStream fileStream)\r\n    {\r\n        <span style=\"color:blue\">this</span>.netStream = netStream;\r\n        <span style=\"color:blue\">this</span>.fileStream = fileStream;\r\n    }\r\n    <span style=\"color:blue\">public</span> <span style=\"color:blue\">override</span> <span style=\"color:blue\">void</span> Write(<span style=\"color:blue\">byte</span>[] buffer, <span style=\"color:blue\">int</span> offset, <span style=\"color:blue\">int</span> count)\r\n    {\r\n        netStream.Write(buffer, offset, count);\r\n        fileStream.Write(buffer, offset, count);\r\n    }\r\n\r\n    <span style=\"color:blue\">public</span> <span style=\"color:blue\">override</span> <span style=\"color:blue\">bool</span> CanRead\r\n    {\r\n        <span style=\"color:blue\">get</span> { <span style=\"color:blue\">return</span> <span style=\"color:blue\">false</span>; }\r\n    }\r\n    <span style=\"color:blue\">public</span> <span style=\"color:blue\">override</span> <span style=\"color:blue\">bool</span> CanSeek\r\n    {\r\n        <span style=\"color:blue\">get</span> { <span style=\"color:blue\">return</span> <span style=\"color:blue\">false</span>; }\r\n    }\r\n    <span style=\"color:blue\">public</span> <span style=\"color:blue\">override</span> <span style=\"color:blue\">bool</span> CanWrite\r\n    {\r\n        <span style=\"color:blue\">get</span> { <span style=\"color:blue\">return</span> (netStream.CanWrite &amp;&amp; fileStream.CanWrite); }\r\n    }\r\n    <span style=\"color:blue\">public</span> <span style=\"color:blue\">override</span> <span style=\"color:blue\">long</span> Length\r\n    {\r\n        <span style=\"color:blue\">get</span> { <span style=\"color:blue\">throw</span> <span style=\"color:blue\">new</span> NotSupportedException(); }\r\n    }\r\n    <span style=\"color:blue\">public</span> <span style=\"color:blue\">override</span> <span style=\"color:blue\">long</span> Position\r\n    {\r\n        <span style=\"color:blue\">get</span>\r\n        {\r\n            <span style=\"color:blue\">throw</span> <span style=\"color:blue\">new</span> NotSupportedException();\r\n        }\r\n        <span style=\"color:blue\">set</span>\r\n        {\r\n            <span style=\"color:blue\">throw</span> <span style=\"color:blue\">new</span> NotSupportedException();\r\n        }\r\n    }\r\n    <span style=\"color:blue\">public</span> <span style=\"color:blue\">override</span> <span style=\"color:blue\">void</span> Flush()\r\n    {\r\n        netStream.Flush();\r\n        fileStream.Flush();\r\n    }\r\n    <span style=\"color:blue\">public</span> <span style=\"color:blue\">override</span> <span style=\"color:blue\">long</span> Seek(<span style=\"color:blue\">long</span> offset, SeekOrigin origin)\r\n    {\r\n        <span style=\"color:blue\">throw</span> <span style=\"color:blue\">new</span> NotSupportedException();\r\n    }\r\n    <span style=\"color:blue\">public</span> <span style=\"color:blue\">override</span> <span style=\"color:blue\">void</span> SetLength(<span style=\"color:blue\">long</span> value)\r\n    {\r\n        <span style=\"color:blue\">throw</span> <span style=\"color:blue\">new</span> NotSupportedException();\r\n    }\r\n    <span style=\"color:blue\">public</span> <span style=\"color:blue\">override</span> <span style=\"color:blue\">int</span> Read(<span style=\"color:blue\">byte</span>[] buffer, <span style=\"color:blue\">int</span> offset, <span style=\"color:blue\">int</span> count)\r\n    {\r\n        <span style=\"color:blue\">throw</span> <span style=\"color:blue\">new</span> NotImplementedException(<span style=\"color:#a31515\">&quot;This is a write only stream&quot;</span>);\r\n    }\r\n    <span style=\"color:blue\">public</span> <span style=\"color:blue\">override</span> <span style=\"color:blue\">void</span> Close()\r\n    {\r\n        netStream.Close();\r\n        fileStream.Close();\r\n    }\r\n}<br><br><br>Any idea why this problem occurs? If not is there a better way for me to write to 2 simultaneous streams?<br><br>thanks for any help<br></pre>\r\n</div>\r\n<p></p>\r\n",
    "PostedDate": "2011-07-07T11:16:26.593-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "638956",
    "ThreadId": "264298",
    "Html": "<p>What's the exception?&nbsp; can you show it?</p>\r\n<p>&nbsp;</p>",
    "PostedDate": "2011-07-07T11:56:56.023-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "638967",
    "ThreadId": "264298",
    "Html": "<p>When the file is in use it gets the \"File is being used by another process\" and if the file is missing it gets a FileNotFound Exception. So its basically throwing the exception twice but one is being caught by the ZipError event but the other one is being thrown from ZipFile.Save</p>",
    "PostedDate": "2011-07-07T12:15:46.28-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "639565",
    "ThreadId": "264298",
    "Html": "<p>Hey Tacker -</p>\r\n<p>here's the problem.&nbsp; When DotNetZip encounters an error opening a file, it invokes your error handler, which tells DotNetZIp to skip that entry.&nbsp; In the general case, DotNetZIp needs to seek back in the output stream, to \"erase\" any output that has already been emitted for that entry.&nbsp; Your output stream is non-seekable, which is why it fails. &nbsp;</p>\r\n<p>Now, In your particular case, there is actually no need to seek backward.&nbsp; In your case, the initial open of the file failed (because the file is locked, in-use), so no output was sent to the output stream at all, therefore there is no seekback required.&nbsp; This is a bug in DotNetZip.&nbsp; I'll change it so that it will try to seek back only if necessary.&nbsp; With that change, DotNetZip will skip the entry if it fails to open, but will still throw an exception, even ify ou want to skip, in the event an IO error is received after open (during read of the source file).&nbsp;</p>\r\n<p>I hope this is clear; ask if not.</p>\r\n<p>&nbsp;</p>",
    "PostedDate": "2011-07-08T10:21:50.85-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "639566",
    "ThreadId": "264298",
    "Html": "This discussion has been copied to a work item. Click <a href=\"http://dotnetzip.codeplex.com/workitem/13903\">here</a> to go to the work item and continue the discussion.",
    "PostedDate": "2011-07-08T10:25:16.487-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "639666",
    "ThreadId": "264298",
    "Html": "<p>That makes sense, thanks for opening a work item, I really appreciate it.</p>",
    "PostedDate": "2011-07-08T13:27:55.457-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "640710",
    "ThreadId": "264298",
    "Html": "<p>Brian, FYI: there's now a prelim binary available for the v1.9.1.6 release. It includes the fix for this.&nbsp;</p>",
    "PostedDate": "2011-07-11T15:59:05.95-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  }
]