2

When using DotNetZip, is it possible to get what the final zip file size will be before calling Save(stream)? I have a website where users will be downloading fairly large zip files (over 2 gigs), and I would like to be able to stream the file to the user rather then buffering the entire file into memory. Some thing like this...

response.BufferOutput = false;
response.AddHeader("Content-Length", ????);

Is this possible?

herbrandson
  • 2,357
  • 2
  • 30
  • 44
  • 2
    I doubt that it is possible, compression algorithms are heavily dependent on input for their output size, and computing the output size is equivalent to doing the compression, so except if you want to multiply by two your server workload you either have to store the file somewhere and then transfer it to the user (ideally directly using your web server file transfer capabilities instead of doing it in code) or as you said do it all in memory (and hope that two users won't need the feature at the same time). – Julien Roncaglia Mar 23 '11 at 08:34
  • 2
    Just as a side-note: The content of the zip file DotNetZip generates is different for non seekable streams since it can't go back to fill in certain header fields. – CodesInChaos Mar 23 '11 at 10:31
  • @herbrandson : Hey you find the way to calculate the zip before save – Saroop Trivedi May 30 '12 at 11:46
  • @sarooptrived: No, per the responses below it is not possible. However, I've since seen a solution to a similar problem using an extension of HTTP that doesn't require a Content-Length header. I believe it uses a null last chunk to signify the end of the stream. Unfortunately, I can't find the link at the moment. – herbrandson May 30 '12 at 17:47
  • @herbrandson: I need the size limitation to passing into network. It's must required to limiting Zip size. Please guide me if you find something. – Saroop Trivedi May 31 '12 at 08:31
  • @herbrandson:Hope this code help you. I did it. http://stackoverflow.com/questions/10815633/dotnetzip-calculate-final-zip-size-before-calling-savestream-in-c-sharp/10815764#comment14077504_10815764 – Saroop Trivedi Jun 01 '12 at 12:12

2 Answers2

3

If the stream is homogenous, you could waste some time by compressing a 'small' portion ahead, calculating the compression ratio and extrapolating from that.

If you are meaning to set a content-length header or something like that, it can only be done when you (1) write a temporary file (advisable if there is any risk of connection trouble and clients requesting specific chunks anyway) (2) can keep the entire file in memory (presumably on ly on 64bit system with copious memory)

Of course, you could waste enormous resources and just compress the stream twice, but I hope you agree that would be silly.

sehe
  • 374,641
  • 47
  • 450
  • 633
1

The way to do what you want is to save the file to a temporary filesystem file, then stream the result to the user. This lets you compute the size then transmit the file.

In this case dotnetzip will not save the file into memory.

Cheeso
  • 189,189
  • 101
  • 473
  • 713