3

I'm trying to zip a bunch of files and make the data consumable via a stream.

I would like to keep the memory footprint as small as possible.

My idea was to implement a Stream where I've got a bunch of FileStream objects as data members. When the Read method on my Stream was called, I would read some data from one of my file streams and use the ZipOutputStream instance to write zipped data to temporary storage stream which i would then forward the read request to.

This temporary storage stream would just be a queue of bytes. As these bytes are moved into a buffer (via a call to Read), they'd be deleted from the queue. This way, I'd only be storing the bytes that haven't been read yet.

Unfortunately, it seems as though when i dispose a ZipOutputStream it needs to write in random file locations in order to create a valid zip file. This will prevent me from using my "fleeting data" solution.

Hopefully this is all clear :)

Is there another way to minimize memory footprint when creating zip files? Please Help!

Thanks!

Jordan
  • 1,599
  • 4
  • 26
  • 42

1 Answers1

1

ZipOutputStream doesn't need to write to random locations in the output stream (in other words, call Seek()). But if the stream you're writing into reports that it CanSeek, it will use that ability to update some headers.

So, make sure that the stream you're writing to returns false for CanSeek() and everything should work fine.

svick
  • 236,525
  • 50
  • 385
  • 514
  • You need to call dispose() on ZipOutputStream in order for it to produce a valid zip file. What does dispose() do, if it doesn't need to seek? – Jordan Feb 07 '12 at 20:46
  • It's similar as with normal output streams: it needs to flush its buffers. And it also writes footers that are required by the file format. – svick Feb 07 '12 at 21:02
  • This mostly worked...now that I've fixed all my bugs. It looks like I was forced to wrap my non-seekable stream in a Ionic.Zip.CountingStream for this to work. Any idea why this is? – Jordan Feb 08 '12 at 17:07
  • It needs the current position in the stream to write some of the metadata and many non-seekable streams don't even let you get their `Position`. `CountingStream` is used to take care of that. From what I read in the source code, I thought wrapping in `CountingStream` happens automatically when it's necessary, but I may be wrong. – svick Feb 08 '12 at 17:32