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

Enable Visual Studio to use more than 2GB of memory

Firefox and Chrome dark mode

Dealing with the morons who built Dell 7710 and RAID