-1

My question is a bit similar to this one but it is with ASP.NET and my requirements are slightly different: Android append files to a zip file without having to re-write the entire zip file?

I need to insert data to a zip-file downloaded by users (not much 1KB of data at most, this is data for Adword off-line conversion actually). The zip-file is downloaded through an ASP.NET website. Because the zip file is already large enough (10's of MB) to avoid overloading the server, I need to insert these data without re-compressing everything. I can think of two ways to do this.

  • Way A: Find a zip-technology that lets embed a particular file in the ZIP file, this particular file being embedded uncompressed. Assuming there is no checksum, it'd be then easy to just override the bits of this un-compressed file with my specific data, in the zip file itself. If possible, this would have to be supported by all unzip tools (Windows integrated zip, winrar, 7zip...).

  • Way B: Append an extra file to the original ZIP file without having to recompress it! This extra file would have to be stored in an embedded folder in the ZIP file.

I looked a bit at SevenZipSharp which has an enumeration SevenZip.CompressionMode with values Create and Append that leads me to think that Way B could be implemented. DotNetZip seems also to work pretty well with Stream according to FAQ.

But if Way A could be possible I'd prefer it much since no extra zip library would be needed on the server side!

Community
  • 1
  • 1
Patrick from NDepend team
  • 13,237
  • 6
  • 61
  • 92
  • 1
    Why if you add a file (way A) you think it'll be recompressed? It won't. Each file zipped in a ZIP archive has its own dictionary (if file is appended or it'll overwrite existing...well it depends on library implementation and case by case). Anyway you have to use an external library (unless you want to manage by yourself zip file format issues). – Adriano Repetti Aug 29 '14 at 14:52
  • Adriano, Way A is not about adding a file, but overriding the content of a file already embedded in the archive, without having to use a zip library for that. – Patrick from NDepend team Aug 29 '14 at 14:56
  • 1
    You can override such file (as I said in comment) only if its size doesn't extend existing one AND to do that you have to handle ZIP file format stuff by yourself. A library will do it for you in the right way (also updating CRC). – Adriano Repetti Aug 29 '14 at 14:58
  • This sounds interesting, you mean that the ZIP library will modify only bits in the ZIP file, relative to the file overridden, with the condition that the new overiden file content is smaller in size than the old one. Is there any documentation somewhere about this? – Patrick from NDepend team Aug 29 '14 at 15:59
  • 1
    Library source code. It's really an implementation detail. – Adriano Repetti Aug 29 '14 at 17:07
  • Thanks so much Adriano, I've been able to achieve what I wanted thanks to your hint, see my answer below! – Patrick from NDepend team Sep 01 '14 at 10:21

1 Answers1

0

Ok, thanks to DotNetZip I am able to do what I want in a very resource efficient way:

using System.IO;
using Ionic.Zip;

class Program {
   static void Main(string[] args) {
      byte[] buffer;
      using (var memoryStream = new MemoryStream()) {
         using (var zip = new ZipFile(@"C:\temp\MylargeZipFile.zip")) {

            // The file on which to override content in MylargeZipFile.zip
            // has the path  "Path\FileToUpdate.txt"
            zip.UpdateEntry(@"Path\FileToUpdate.txt", @"Hello My New Content");
            zip.Save(memoryStream);
         }
         buffer = memoryStream.ToArray();
      }
      // Here the buffer will be sent to httpResponse
      // httpResponse.Clear();
      // httpResponse.AddHeader("Content-Disposition", "attachment; filename=MylargeZipFile.zip");
      // httpResponse.ContentType = "application/octe-t-stream";
      // httpResponse.BinaryWrite(buffer);
      // httpResponse.BufferOutput = true;

      // Just to check it worked!
      File.WriteAllBytes(@"C:\temp\Result.zip", buffer);
   }
}
Patrick from NDepend team
  • 13,237
  • 6
  • 61
  • 92