Compression & Decompression in C#

Many people search for this. Note I have XML serialized the object because if you do binary serialization, if there are breaking changes in the class, then it will not de-serialize.

To compress, do this:


CompressionOutput output = new CompressionOutput();
            byte[] xmlBytes = Encoding.UTF8.GetBytes(largeString);
            MemoryStream memoryStream = new MemoryStream();

            try
            {
                using (GZipStream zipStream = new GZipStream(memoryStream, CompressionMode.Compress))
                {
                    try
                    {
                        zipStream.Write(xmlBytes, 0, xmlBytes.Length);
                    }
                    finally
                    {
                        zipStream.Flush();
                        zipStream.Close();
                    }
                }

                byte[] compressedData = memoryStream.ToArray();              

                if (compressedData.Length < xmlBytes.Length)
                {
                    output.Compressed = true;
                    output.Output = compressedData;
                }
                else
                {
                    output.Compressed = false;
                    output.Output = xmlBytes;
                }

                return output;
            }
            catch (Exception ex)
            {
                //Need to handle exception
                output.Compressed = false;
                output.Output = xmlBytes;
                return output;
            }

To Decompress:


if (!compressed)
            {
                return Encoding.UTF8.GetString(smallByteArray);
            }

            byte[] outputBytes = null;

            using (MemoryStream inputStream = new MemoryStream(smallByteArray))
            {
                byte[] sizeBytes = new byte[4];
                inputStream.Position = inputStream.Length - 5;
                inputStream.Read(sizeBytes, 0, 4);
                inputStream.Position = 0;
                int size = BitConverter.ToInt32(sizeBytes, 0);

                byte[] readBuffer = new byte[size + 101];
                int readOffset = 0;
                int decompressedByteArrayLength = 0;

                try
                {
                    using (GZipStream zipStream = new GZipStream(inputStream, CompressionMode.Decompress))
                    {
                        try
                        {
                            while (true)
                            {
                                int bytesDecompressed = zipStream.Read(readBuffer, readOffset, 100);
                                if (bytesDecompressed == 0) { break; }

                                readOffset += bytesDecompressed;
                                decompressedByteArrayLength += bytesDecompressed;
                            }
                        }
                        finally
                        {
                            zipStream.Close();
                        }
                    }
                }
                finally
                {
                    inputStream.Close();
                }

                outputBytes = new byte[decompressedByteArrayLength];
                Array.ConstrainedCopy(readBuffer, 0, outputBytes, 0, decompressedByteArrayLength);
            }          

            return Encoding.UTF8.GetString(outputBytes);

Comments

Popular posts from this blog

Tutorial: Using Google Cloud Storage from C# and .NET

Late 2008 Macbook only giving 1.5 gb/s speed with 6 gb/s Intel SSD?

Enable Visual Studio to use more than 2GB of memory