SharpZipLib to compress a string

Roger picture Roger · Mar 22, 2012 · Viewed 8.3k times · Source

I need to compress a string to reduce the size of a web service response. I see the unit tests in the SharpZipLib samples, but not an example of exactly what I need.

In the following code, the constructor for ZipOutputStream returns the exception: "No open entry"

        byte[] buffer = Encoding.UTF8.GetBytes(SomeLargeString);
        Debug.WriteLine(string.Format("Original byes of string: {0}", buffer.Length));

        MemoryStream ms = new MemoryStream();
        using (ZipOutputStream zipStream = new ZipOutputStream(ms))
        {
            zipStream.Write(buffer, 0, buffer.Length);
            Debug.WriteLine(string.Format("Compressed byes: {0}", ms.Length));
        }

        ms.Position = 0;
        MemoryStream outStream = new MemoryStream();

        byte[] compressed = new byte[ms.Length];
        ms.Read(compressed, 0, compressed.Length);

        byte[] gzBuffer = new byte[compressed.Length + 4];
        System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
        System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);
        string compressedString = Convert.ToBase64String (gzBuffer);

Where did I get off track? Am I making this more complex than it should be?

Answer

kikea picture kikea · Dec 31, 2014

For web service communication compression data from Silverlight I use this snippet:

private byte[] zipText(string text)
{
    if (text == null)
        return null;

    using(Stream memOutput = new MemoryStream())
    {
        using (GZipOutputStream zipOut = new GZipOutputStream(memOutput))
        {
            using (StreamWriter writer = new StreamWriter(zipOut))
            {
                writer.Write(text);

                writer.Flush();
                zipOut.Finish();

                byte[] bytes = new byte[memOutput.Length];
                memOutput.Seek(0, SeekOrigin.Begin);
                memOutput.Read(bytes, 0, bytes.Length);

                return bytes;
            }
        }
    }
}

private string unzipText(byte[] bytes)
{
    if (bytes == null)
        return null;

    using(Stream memInput = new MemoryStream(bytes))
    using(GZipInputStream zipInput = new GZipInputStream(memInput))
    using(StreamReader reader = new StreamReader(zipInput))
    {
        string text = reader.ReadToEnd();

        return text;
    }
}
  1. I used GZip instead of Zip compression
  2. Expected that text will be read/write from the similar environment, so I didn't do any extra encoding/decoding.

My case was the compression of the json data. From my observation in some cases the text data of about 95Kb was compressed to 1.5Kb. So even the data will be serialized into base 64, anyway are good traffic saving.

Posted my answer that may be for somebody some time saving.