{
  "WorkItem": {
    "AffectedComponent": {
      "Name": "",
      "DisplayName": ""
    },
    "ClosedComment": "This feature is added in change set 24040.\nThere is a new callback on the ZipEntry and ZipFile classes, to handle this particular case.",
    "ClosedDate": "2008-09-08T16:09:48.103-07:00",
    "CommentCount": 0,
    "Custom": null,
    "Description": "By default, when saving a zip, if the compression causes an expansion of the file data size, then the input stream is read twice.  \nThis happens with ZipEntry.WriteHeader(). \n \nAs I use a database as an input stream, and the stream is about 2 MB large,  this double-read behavior is rather \"expensive\", because the blob has to be fetched twice from the DB.\n \nThe two positions are (changeset 22632):\n \nLine 1626\n                                _Crc32 = crc32.GetCrc32AndCopy(_inputStream, CompressedStream);\n \n \nand again Line 1662:\n                                _Crc32 = crc32.GetCrc32AndCopy(_inputStream, _UnderlyingMemoryStream);\n \n \nIs there a way to chage this so the call to GetCrc32AndCopy is done only once (and I do not not want to set _ForceNoCompression to true)? \nPerhaps the two things can be done in one step?\n \nIf it is too complex changing this then its by design, and its ok, but if ou have an idea changing this it would be great.\n \nby the way, my classes for streamed and chunked steams from db ore anywhere else  from are attached.",
    "LastUpdatedDate": "2013-05-16T05:32:40.31-07:00",
    "PlannedForRelease": "",
    "ReleaseVisibleToPublic": false,
    "Priority": {
      "Name": "Low",
      "Severity": 50,
      "Id": 1
    },
    "ProjectName": "DotNetZip",
    "ReportedDate": "2008-08-26T03:30:48.127-07:00",
    "Status": {
      "Name": "Closed",
      "Id": 4
    },
    "ReasonClosed": {
      "Name": "Unassigned"
    },
    "Summary": "Writing zip with previously-compressed file data reads the stream twice",
    "Type": {
      "Name": "Issue",
      "Id": 3
    },
    "VoteCount": 1,
    "Id": 5829
  },
  "FileAttachments": [
    {
      "FileId": 1269,
      "FileName": "ChunkedStream.cs",
      "DownloadUrl": ".\\1269"
    }
  ],
  "Comments": [
    {
      "Message": "to use these lasses:\r\n\r\nread from an archive stored in db:\r\n\r\n            using (DatabaseChunkedReadingStream readingStream = new DatabaseChunkedReadingStream(this, idZipElement) )\r\n            {\r\n                using (ZipFile zip = ZipFile.Read(readingStream))\r\n                {\r\n                    foreach (ZipEntry entry in zip)\r\n                    {\r\n...\r\n\r\n\r\nwrite an archive to db\r\n\r\n    using( DatabaseChunkedWritingStream repository = new DatabaseChunkedWritingStream(this, idElement) )\r\n    {\r\n        using (ZipFile zip = new ZipFile(repository))\r\n        {\r\n            // add elemens to zip \r\n            ...\r\n\r\n            zip.Save();\r\n        }\r\n    }\r\n\r\n",
      "PostedDate": "2008-08-26T03:35:36.95-07:00",
      "Id": -2147483648
    },
    {
      "Message": "Mausoma, good catch.   I will have a look  and figure out a better design for this.   Thanks for the example source.\r\n",
      "PostedDate": "2008-08-27T08:33:00.403-07:00",
      "Id": -2147483648
    },
    {
      "Message": "Mausoma, what would you prefer the library to do in this case?   The code path you are talking about is this.  The library attempts to zip a stream.  The compressed size of the stream is actually larger than the original size.  In this case the library reads the stream again, and this time does not compress.  This results in a smaller zip archive as output.  \r\n\r\nI think what you are saying is, you don't care about the size of the output.  You would rather have the zip library NOT read the stream again, even in the case where the \"compression\" expands the file data.  \r\n\r\nI can imagine 2 ways to address this.  One way is to cache all the filedata until the compressed-versus-uncompressed size comparison can be done. If the compressed size is larger, then we re-read the filedata from the cache, not from the original stream.  This seems like a really bad idea because it will cause poor memory behavior.  It violates the principle of the using streams. \r\n\r\nThe second way is to add a flag, similar to \"ForceNoCompression\" which effectively says \"AlwaysUseCompression\".   If either of the prior flags are set, we read the stream only once.  We might call the new flag \"ForceCompression\".   In that way it is a complement to ForceNoCompression.  ForceNoCompression reads the stream only once, doesn't use compression, and skips the comparison and potential re-read.  ForceCompression might read the stream once, use compression, and skip the comparison.  It's really a three-way switch on the behavior you want.  So in that respect, it might make sense to model it as an Enum.  \r\n\r\nWhat do you think? \r\n\r\n\r\n\r\n",
      "PostedDate": "2008-08-28T17:36:32.11-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2008-08-28T17:51:43.027-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2008-08-28T17:51:43.903-07:00",
      "Id": -2147483648
    },
    {
      "Message": "Well, all your points are legitime, as all possible soultions have some advantages and some disadvantages.\r\n\r\nSpoken in words, what would be the best FOR ME (just one individual) is something like:\r\n\r\nif(  (compressedSize > 1MB)  && (compressedSize > 20% more than original size)\r\n   take original stream (to be read again)\r\nelse\r\n  take compressed stream (no further reading)\r\n\r\nThats very special, I know.\r\n\r\nPerhaps one could achieve this by OVERLOADING some functionality, like\r\n\r\npublic virtual bool ReloadIfCompressionIsLargerThanOriginal(long original size, long comressied size, string filename,  some other parameters like stream ? )\r\n{\r\n     return true; // defaults rereads stream\r\n}\r\n\r\nand using it:\r\n\r\npublic class MyZipFile : ZipFile\r\n{\r\n  public override bool ReloadIfCompressionIsLargerThanOriginal(...)\r\n  {\r\n     ... // my own implementation\r\n  }\r\n\r\n}",
      "PostedDate": "2008-08-29T00:48:07.8-07:00",
      "Id": -2147483648
    },
    {
      "Message": "Hmm, ok I can imagine adding a callback into the ZipFile class that would invoke your logic for that particular event.  \r\nI can imagine that it would be pretty simple and clean to implement.  I am not sure how mainstream it would be, though.  Your requirements here seem to be pretty specific. \r\n\r\nI will have to think about what the best thing to do is. \r\nIn the meantime you can of course modify the code for yourself and insert the check you need. \r\n\r\n\r\n",
      "PostedDate": "2008-08-29T07:02:44.11-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2008-09-08T16:09:48.103-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2013-02-21T18:44:42.563-08:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2013-05-16T05:32:40.31-07:00",
      "Id": -2147483648
    }
  ]
}