Decompressing a Memory Stream

Sep 14, 2011 at 1:05 PM

I have some XML data which is returned as a string from a HTTP request. The string is compress using gzip and needs uncompressing.

I have implemented the following method to achieve this but keep getting an error:

 public static string DecompressString(string zippedString)
        {
            string result = string.Empty;

            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(zippedString)))
            {
                ms.Position = 0;
                using (ZipFile zip = ZipFile.Read(ms))
                {
                    if (zip.Count > 0)
                    {
                        ZipEntry entry = zip[0]; // there should only be one entry

                        if (entry != null)
                        {
                            using (MemoryStream output = new MemoryStream())
                            {
                                entry.Extract(output);
                                output.Position = 0;

                                StreamReader sr = new StreamReader(output);
                                result = sr.ReadToEnd();
                            }
                        }
                    }
                }
            }

            return result;
        }

The error I get is: zipentry::readheader(): bad signature (0xb980e21f) at position  0x00000000" which occurs then I attempt to read the memory stream


Coordinator
Sep 14, 2011 at 6:26 PM

ok, first thing - if you are using HttpWebRequest to retrieve the information, you can easily enable automatic decompression, without using DotNetZip or any decompression library.   Check this:  http://stackoverflow.com/questions/2815721/net-is-it-possible-to-get-httpwebrequest-to-automatically-decompress-gzipd-res

But you said that it is an XML file, and there's a string involved, and so on, so I'm not sure that will apply to you.

Next: If you have data that is GZip'd then you cannot use ZipFile to decompress it.  GZIP is a different format, and you cannot read a GZip stream using DotNetZip's ZipFile class.  There is a class in the DotNetZip library for compressing and decompressing a GZip - Ionic.Zlib.GZipStream.  If you need to decompress manually  - if the automatic decompression I mentioned above does not work - then use GZipStream, not ZipFile.

Last thing: I don't know where you got your zippedString, but I am certain that You cannot call Encoding.UTF8.GetBytes(zippedString) and expect to get a byte array that is GZIP compressed.  Calling GetBytes() on it will not give you anything that GZipStream can read.  You need to do a little more research on exactly how that zippedString is created.  I suppose it may be a string which results from applying a transformation to an array of bytes.  In some cases an app will base64-encode array of bytes in order to transform it into a printable string.  In other cases an  app will hex encode the original data. There are other options.  You need to understand the transformation that was applied to the original data in order to get the zippedString thing, and apply the reverse transformation in your app to recover the initial data.  Base64-decode or hex-decode, or etc. Then you will have an array of bytes.  The next step is to apply the reverse transformation to that byte array - in your case that could be GZip decompression, which, as I said above, you can do with the GZipStream.  

 

Sep 15, 2011 at 8:51 AM

Thanks for the reply, I have the auto decompression working fine now.