[
  {
    "Id": "260296",
    "ThreadId": "76110",
    "Html": "<p>Executing the code below gives me a</p>\r\n<p>&nbsp;NotSupportedException: Specified Method is not supported.</p>\r\n<p>Stacktrace:</p>\r\n<pre>   at System.Web.HttpResponseStream.get_Position()\r\n   at Ionic.Zip.ZipEntry.WriteHeader(Stream s, Int32 cycle)\r\n   at Ionic.Zip.ZipOutputStream._InitiateCurrentEntry(Boolean finishing)\r\n   at Ionic.Zip.ZipOutputStream.Write(Byte[] buffer, Int32 offset, Int32 count)\r\n   at PageTest.streamZipToClient2(HttpResponse response, String zipFileName, String zipFileBaseDirectory, String physicalBasePath, IEnumerable`1 physicalFilePaths) in c:\\Entwicklung\\Projekte\\PoolarServer\\ClientName\\trunk\\PageTest.aspx.cs:line 74</pre>\r\n<p>I need to do it this way because I check for Response.IsClientConnected while streaming in the data (some file are &gt;1GB).<br>A compromise would be to just check after each entry addition, but I couldn't find a way to do that either (ZipOutputStream has no Write(Stream stream). And a ZipFile would not begin streaming before calling save.</p>\r\n<p>Any tips here?</p>\r\n<p>Many thanks!</p>\r\n<p>Code:<br><br></p>\r\n<div style=\"color:Black;background-color:White\">\r\n<pre>    <span style=\"color:Blue\">protected</span> <span style=\"color:Blue\">void</span> Page_Load(<span style=\"color:Blue\">object</span> sender, EventArgs e)\r\n    {\r\n        <span style=\"color:Blue\">var</span> fileInfos = <span style=\"color:Blue\">new</span> List&lt;<span style=\"color:Blue\">string</span>&gt; { \r\n        <span style=\"color:#A31515\">@&quot;C:\\Temp\\sub1\\file1.pdf&quot;</span>, <span style=\"color:#A31515\">@&quot;C:\\Temp\\sub1\\file2.gz&quot;</span>, <span style=\"color:#A31515\">@&quot;C:\\Temp\\sub1\\file3.bak&quot;</span>\r\n        };\r\n        streamZipToClient2(Response, <span style=\"color:#A31515\">&quot;test.zip&quot;</span>, <span style=\"color:#A31515\">&quot;myzip&quot;</span>, <span style=\"color:#A31515\">@&quot;C:\\Temp\\&quot;</span>, fileInfos);\r\n\r\n        HttpContext.Current.ApplicationInstance.CompleteRequest();\r\n    }\r\n\r\n\r\n    <span style=\"color:Blue\">static</span> <span style=\"color:Blue\">bool</span> streamZipToClient2(HttpResponse response, <span style=\"color:Blue\">string</span> zipFileName, <span style=\"color:Blue\">string</span> zipFileBaseDirectory, <span style=\"color:Blue\">string</span> physicalBasePath, IEnumerable&lt;<span style=\"color:Blue\">string</span>&gt; physicalFilePaths)\r\n    {\r\n        response.Clear();\r\n        response.Buffer = <span style=\"color:Blue\">false</span>;\r\n\r\n        <span style=\"color:Blue\">long</span> approximateZipFileSize = 0;\r\n\r\n        <span style=\"color:Blue\">foreach</span> (<span style=\"color:Blue\">var</span> filePath <span style=\"color:Blue\">in</span> physicalFilePaths)\r\n        {\r\n            approximateZipFileSize += (<span style=\"color:Blue\">new</span> FileInfo(filePath)).Length;\r\n        }\r\n\r\n        response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);\r\n        response.Cache.SetNoStore();\r\n        response.Cache.SetExpires(DateTime.UtcNow.AddYears(-1));\r\n\r\n        response.ContentType = <span style=\"color:#A31515\">&quot;application/zip&quot;</span>;\r\n        response.AddHeader(<span style=\"color:#A31515\">&quot;content-disposition&quot;</span>, <span style=\"color:#A31515\">&quot;filename=&quot;</span> + zipFileName);\r\n        response.AddHeader(<span style=\"color:#A31515\">&quot;content-length&quot;</span>, (approximateZipFileSize * 1.2).ToString());\r\n\r\n        <span style=\"color:Blue\">using</span> (<span style=\"color:Blue\">var</span> zipStream = <span style=\"color:Blue\">new</span> Ionic.Zip.ZipOutputStream(response.OutputStream))\r\n        {\r\n                zipStream.CompressionLevel = Ionic.Zlib.CompressionLevel.None;\r\n                <span style=\"color:Blue\">int</span> bufferSize = 1024 * 1024;\r\n                <span style=\"color:Blue\">var</span> buffer = <span style=\"color:Blue\">new</span> <span style=\"color:Blue\">byte</span>[bufferSize];\r\n                <span style=\"color:Blue\">foreach</span> (<span style=\"color:Blue\">var</span> physicalFilePath <span style=\"color:Blue\">in</span> physicalFilePaths)\r\n                {\r\n                    <span style=\"color:Blue\">using</span> (<span style=\"color:Blue\">var</span> fileStream = File.OpenRead(physicalFilePath))\r\n                    {\r\n                        <span style=\"color:Blue\">string</span> relativeFilePath = physicalFilePath.Replace(physicalBasePath, <span style=\"color:#A31515\">&quot;&quot;</span>);\r\n                        <span style=\"color:Blue\">string</span> fileName = Path.GetFileName(physicalFilePath);\r\n                        <span style=\"color:Blue\">string</span> directoryInZipFile = Path.Combine(zipFileBaseDirectory, relativeFilePath.Replace(fileName, <span style=\"color:#A31515\">&quot;&quot;</span>));\r\n                        <span style=\"color:Blue\">string</span> entryName = Path.Combine(directoryInZipFile, fileName);\r\n\r\n                        zipStream.PutNextEntry(entryName);\r\n\r\n                        <span style=\"color:Blue\">long</span> remaining = fileStream.Length;\r\n                        <span style=\"color:Blue\">while</span> (remaining &gt; 0)\r\n                        {\r\n                            <span style=\"color:Blue\">if</span> (!response.IsClientConnected)\r\n                            {\r\n                                <span style=\"color:Blue\">return</span> <span style=\"color:Blue\">false</span>;\r\n                            }\r\n                            <span style=\"color:Blue\">int</span> read = fileStream.Read(buffer, 0, bufferSize);\r\n                            remaining -= read;\r\n\r\n                            zipStream.Write(buffer, 0, read);                           \r\n                        }\r\n                    }\r\n                }\r\n        }\r\n        <span style=\"color:Blue\">return</span> <span style=\"color:Blue\">true</span>;\r\n    }\r\n</pre>\r\n</div>",
    "PostedDate": "2009-11-24T10:43:16.927-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "260331",
    "ThreadId": "76110",
    "Html": "<p>looks like a bug to me. . .</p>\r\n<p>I'll need to look closer, and get back to you.</p>\r\n<p>&nbsp;</p>",
    "PostedDate": "2009-11-24T12:04:13.543-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "260419",
    "ThreadId": "76110",
    "Html": "<p>That would be very nice, thank you.</p>\r\n<p>As soon as I've integrated the zipping code into the rest of the application, there will be some testing of the streamed archives on Mac computers. I will feed back the results (as there still seems to be some uncertainty about that issue)</p>",
    "PostedDate": "2009-11-24T15:44:25.687-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "260682",
    "ThreadId": "76110",
    "Html": "This discussion has been copied to a work item. Click <a href=\"http://dotnetzip.codeplex.com/WorkItem/View.aspx?WorkItemId=9307\">here</a> to go to the work item and continue the discussion.",
    "PostedDate": "2009-11-25T10:23:29.613-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "263907",
    "ThreadId": "76110",
    "Html": "<p>ps: I think you should use Response.Close() instead of</p>\r\n<p>HttpContext.Current.ApplicationInstance.CompleteRequest();</p>",
    "PostedDate": "2009-12-05T05:01:09.363-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "268828",
    "ThreadId": "76110",
    "Html": "<p>I needed to do exactly the same as above and got the same exception.</p>\r\n<p>I encounter it with Response buffer set to false. The internal stream usage needs to know it stream position, but there is no code for wrapping the write-only stream in a CountingStream.</p>\r\n<p>So, I've fixed the bug by changing _Init() in Ionic.Zip.ZipOutputStream as follows:</p>\r\n<div style=\"color:Black;background-color:White\">\r\n<pre>        <span style=\"color:Blue\">private</span> <span style=\"color:Blue\">void</span> _Init(Stream stream, <span style=\"color:Blue\">bool</span> leaveOpen)\r\n        {\r\n            _outputStream = stream.CanRead ? stream : new CountingStream(stream);<br>            CompressionLevel = Ionic.Zlib.CompressionLevel.Default;\r\n            _encryption = EncryptionAlgorithm.None;\r\n            _entriesWritten = <span style=\"color:Blue\">new</span> List&lt;ZipEntry&gt;();\r\n            _zip64 = Zip64Option.Never;\r\n            _leaveUnderlyingStreamOpen = leaveOpen;\r\n            Strategy = Ionic.Zlib.CompressionStrategy.Default;\r\n            _name = <span style=\"color:#A31515\">&quot;unknown&quot;</span>;\r\n<span style=\"color:Blue\">#if</span> !NETCF    \r\n            ParallelDeflateThreshold = -1L;\r\n<span style=\"color:Blue\">#endif</span>\r\n        }\r\n</pre>\r\n<pre>\r\nI hope this helps someone else, and that this fix (or possibly a &quot;better&quot; solution makes it into the official release as soon as possible (so I don't have to keep a separate branch myself...) :)</pre>\r\n</div>",
    "PostedDate": "2009-12-18T01:21:44.137-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "268961",
    "ThreadId": "76110",
    "Html": "<p>Aquamoth, thanks, that's helpful.&nbsp;</p>\r\n<p>The fix will be in vv1.9.0.33.</p>",
    "PostedDate": "2009-12-18T08:34:05.37-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  }
]