Freigeben über


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

  • Anonymous
    March 14, 2006
    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?

  • Anonymous
    March 14, 2006
    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.

  • Anonymous
    March 14, 2006
    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.

  • Anonymous
    April 17, 2006
    The AppDev: Something You Should Know is a great blog to read/subscribe to, it has loads of useful...

  • Anonymous
    February 15, 2007
    does this work for binary data mixed with ascii data as well. Say you have an email with a binary attachment.

  • Anonymous
    February 15, 2007
    Haven't tried, but I would expect that it works...

  • Anonymous
    May 15, 2009
    Is it possible to have the zip file exracted into files with the same name as the file inside?