{
  "WorkItem": {
    "AffectedComponent": {
      "Name": "",
      "DisplayName": ""
    },
    "ClosedComment": "This idea is not going to work with the design of DotNetZip as it is. ",
    "ClosedDate": "2009-08-28T21:22:47.003-07:00",
    "CommentCount": 0,
    "Custom": null,
    "Description": "Consider adding an AutoSave property on the ZipFile, which will save the file after every AddFile(), AddFiles(), AddSelectedFiles(), AddDirectory(), and so on.",
    "LastUpdatedDate": "2013-05-16T05:32:19.29-07:00",
    "PlannedForRelease": "",
    "ReleaseVisibleToPublic": false,
    "Priority": {
      "Name": "Medium",
      "Severity": 100,
      "Id": 2
    },
    "ProjectName": "DotNetZip",
    "ReportedDate": "2009-06-05T09:23:13.92-07:00",
    "Status": {
      "Name": "Closed",
      "Id": 4
    },
    "ReasonClosed": {
      "Name": "Unassigned"
    },
    "Summary": "ZipFile.AutoSave - save ZipFile after every AddXxx() or RemoveXxx()",
    "Type": {
      "Name": "Feature",
      "Id": 1
    },
    "VoteCount": 1,
    "Id": 7861
  },
  "FileAttachments": [],
  "Comments": [
    {
      "Message": "Hi everyone. If the idea is to physically write the ZIP file on disk everytime, perhaps it will not a good one if you must to include in a single ZIP file thousands of other files (as is my case).\r\n\r\nMaybe it would better to implement a 'Realize()' method in the ZipItem object, which in-memory compresses the input object (string, byte array, file or stream), leaving it ready-to-write when the Save() method will be called later, and releasing the input object, in order the calling program can dispose and free it, or reuse it.\r\n\r\nLater, when the Save() method is called, if a given ZipItem is flagged as 'Realized', it  simply will write to disk the already compressed buffer, and if not, it will perform the compression-and-write, as it's doing now.\r\n\r\nIn order to keep compatibility with the \"just-in-time stream provisioning\" technique when passing Null-Nothing to the 'AddFileStream()' method, the proposed 'ZipItem.Realize()' method should raise an error \"No input object to realize.\"\r\n",
      "PostedDate": "2009-06-08T04:30:30.063-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2009-06-16T08:21:38.343-07:00",
      "Id": -2147483648
    },
    {
      "Message": "Hmm, Ricardo, the idea for a Realize() method seems like a different thing entirely.   \r\n\r\nThe problem with the approach you describe is that it implies keeping all of the zip content in memory.  This can be a large amount of memory, possibly multiple gigabytes for a large file.  It seems like a very bad idea to allow this.  In fact in the early versions of DotNetZip, I used such an approach to create the zip file when saving, but not surprisingly, it caused many problems for people.  So at some point (long ago) I converted the compression/encryption to use a streaming approach, so that large files could be compressed using only a small amount of memory.   The proposed Realize() method would encourage some very bad habits, I am afraid.   \r\n\r\nI think I understand your motivation for a proposed AutoSave capability, and like you, I have concerns about the performance implications of such an approach.  My current thinking is that it would be impractical.  Your proposed Realize() method will make things faster, but very very memory-inefficient.  At this point I think neither approach is practical.  \r\n\r\nAs an alternative, it may be possible to implement AutoSave by writing only the \"delta\" for each new entry added.  Instead of writing thousands of zip entries every time the list of entries changes, it may be possible to write just one entry.  This idea bears further consideration.",
      "PostedDate": "2009-06-16T08:33:18.04-07:00",
      "Id": -2147483648
    },
    {
      "Message": "Sorry for my 'silence', I've been out for some days.\r\n\r\nWell, if you have concerns about memory requirements, just use temporary files! ;-)\r\n\r\nBut seriously. Still let's imagine you could implement the Realize() method in the ZipItem object. The default behavior should be as up to now, i.e., don't realize the compression of the input items. It should be up to the programmers to decide to perform the realization or not, by calling the Realize() method, being aware of the limitations. \r\n\r\nMaybe the method could have a 'threshold' parameter, given in KB, by which the compressed buffer will kept in memory only if it is under this value, or dumped to a private temporary file if it's above. This way, programmers can control the performance of the library at their own criteria, beyond the default behaviour.\r\n\r\nWhen the Save() method will being called, then it 'assembles' the compressed portions (already realized or not) into the single resulting ZIP file.\r\n\r\nYours.",
      "PostedDate": "2009-06-20T01:05:27.923-07:00",
      "Id": -2147483648
    },
    {
      "Message": "By 'ZipItem object' I meant the 'ZipEntry object', sorry.",
      "PostedDate": "2009-06-20T01:58:11.467-07:00",
      "Id": -2147483648
    },
    {
      "Message": "Hmm, I was thinking around this topic, and perhaps I found a \"Solomon's solution\".\r\n\r\nWhen the proposed 'ZipEntry.Realize()' method were called, and only if it has a valid/open associated source, the library will perform the in-memory/temporary file dump compression (depending on the already proposed threshold value) of the given source, and making the result item the *NEW SOURCE* for the ZipEntry object, marking it as 'Realized', and releasing the original input source. That is, *ACTIVELY CHANGING* the original input source of the ZipEntry object for a new sinthesized, compressed/encrypted one.\r\n\r\nWhen the Save() method is called, if a given ZipEntry object is marked as 'Realized', the entry in the ZIP directory is written as ordinary, but the binary, already compressed/encrypted data, stored as the new source, is dumped as if it was marked as 'ForceNoCompression'.\r\n\r\nDo you like this option?\r\n",
      "PostedDate": "2009-06-20T02:14:11.96-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2009-08-28T21:22:47.003-07:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2013-02-21T18:44:15.397-08:00",
      "Id": -2147483648
    },
    {
      "Message": "",
      "PostedDate": "2013-05-16T05:32:19.29-07:00",
      "Id": -2147483648
    }
  ]
}