SYSK 82: Compression Example in .NET


As many of you may know, .NET framework 2.0 contains a built in support for compressing the file or any generic stream such as FileStream, MemoryStream, TextWriter, XmlWriter, NetworkStream, etc


 


So, now, you can compress/decompress using GZip algorithm natively in .NET.  The code below is an example of compressing/decompressing a file.  To run it, create a C# Windows Application project, add a button to your form and create source.txt file with some text (e.g. Hello, World!) in c:\temp\compression folder.


 


private void button1_Click(object sender, EventArgs e)


{


    Compress(@”c:\temp\compression\source.txt”, @”c:\temp\compression\compressed.txt”);


    DeCompress(@”c:\temp\compression\compressed.txt”, @”c:\temp\compression\result.txt”);


}


 


private void Compress(string source, string destination)


{


    using (System.IO.FileStream sourceStream = System.IO.File.OpenRead(source))


    {


        using (System.IO.FileStream destinationStream = System.IO.File.OpenWrite(destination))


        {


            using (System.IO.Compression.GZipStream compressedStream = new System.IO.Compression.GZipStream(destinationStream, System.IO.Compression.CompressionMode.Compress))


            {


 


                byte[] data = new byte[sourceStream.Length];


                sourceStream.Read(data, 0, data.Length);


 


                compressedStream.Write(data, 0, data.Length);


            }


        }               


    }


}


 


private void DeCompress(string source, string destination)


{


    using (System.IO.FileStream sourceStream = System.IO.File.OpenRead(source))


    {


        using (System.IO.FileStream destinationStream = System.IO.File.OpenWrite(destination))


        {


            using (System.IO.Compression.GZipStream decompressedStream = new System.IO.Compression.GZipStream(sourceStream, System.IO.Compression.CompressionMode.Decompress))


            {


                // Note: decompressedStream.Length is not supported => results in runtime exception


                int data;


                while ((data = decompressedStream.ReadByte()) != -1)


                    destinationStream.WriteByte((byte)data);                       


            }


        }


    }


}

Comments (7)

  1. Jeff Parker says:

    You know I seen this but I do not seem to find the gotcha’s with using this method. However my own experiments have left me wondering about this. Now this seem to work great for any text based streams, however binary streams seem to be a little wacky. Some of the streams I have "Compressed" actually turn out much larger in file size. I can not figure this one out. Any clue into this behavior?

  2. JohnGalt says:

    Except that if you compress a stream and then expand it immediately afterwards it won’t expand anything because when you do a .Read() on the gZip stream it will return 0 instead of the length it read. The second call to .Read() will work correctly, but then the resultant decompressed stream will be one byte short (truncated off of the end)

    You can see this with an XML file that you load in as a stream.

  3. irenak says:

    File-compression programs simply get rid of the redundancy.  Graphics, MP3 files, and other binary files include a lot of unique information, so they don’t compress well.  You may want to read "SYSK 81: How compression works" blog post.

  4. The AppDev: Something You Should Know is a great blog to read/subscribe to, it has loads of useful…

  5. does this work for binary data mixed with ascii data as well. Say you have an email with a binary attachment.

  6. irenak says:

    Haven’t tried, but I would expect that it works…

  7. John says:

    Is it possible to have the zip file exracted into files with the same name as the file inside?