Corey Ogburn
Corey Ogburn

Reputation: 24759

GZipStream not compressing?

I'm trying to zip a memory stream into another memory stream so I can upload to a rest API. image is the initial memory stream containing a tif image.

WebRequest request = CreateWebRequest(...);
request.ContentType = "application/zip";
MemoryStream zip = new MemoryStream();
GZipStream zipper = new GZipStream(zip, CompressionMode.Compress);
image.CopyTo(zipper);
zipper.Flush();
request.ContentLength = zip.Length; // zip.Length is returning 0
Stream reqStream = request.GetRequestStream();
zip.CopyTo(reqStream);
request.GetResponse().Close();
zip.Close();

To my understand, anything I write to the GZipStream will be compressed and written to whatever stream was passed into it's constructor. When I copy the image stream into zipper, it appears nothing is actually copied (image is 200+ MB). This is my first experience with GZipStream so it's likely I'm missing something, any advice as to what would be greatly appreciated.

EDIT: Something I should note that was a problem for me, in the above code, image's position was at the very end of the stream... Thus when I called image.CopyTo(zipper); nothing was copied due to the position.

Upvotes: 1

Views: 2625

Answers (3)

Paŭlo Ebermann
Paŭlo Ebermann

Reputation: 74800

I don't know anything about C# and its libraries, but I would try to use Close instead of (or after) Flush first.

(Java's GZipOutputStream has the same problem that it doesn't properly flush, until Java 7.)

Upvotes: 0

Rob Levine
Rob Levine

Reputation: 41328

[Edited: to remove incorrect info on GZipStream and it's constructor args, and updated with the real answer :) ]

After you've copied to the zipper, you need to shift the position of the MemoryStream back to zero, as the process of the zipper writing to the memory stream advances it's "cursor" as well as the stream being read:

WebRequest request = CreateWebRequest(...);
request.ContentType = "application/zip";
MemoryStream zip = new MemoryStream();
GZipStream zipper = new GZipStream(zip, CompressionMode.Compress);
image.CopyTo(zipper);
zipper.Flush();
zip.Position = 0; // reset the zip position as this will have advanced when written to.
...

One other thing to note is that the GZipStream is not seekable, so calling .Length will throw an exception.

Upvotes: 3

thekip
thekip

Reputation: 3768

See this example: http://msdn.microsoft.com/en-us/library/system.io.compression.gzipstream.flush.aspx#Y300

You shouldn't be calling flush on the stream.

Upvotes: -1

Related Questions