Tallan's Technology Blog

Tallan's Top Technologists Share Their Thoughts on Today's Technology Challenges

Compression using the GZipStream and DeflateStream in .NET

Reddy Kadasani
What is GZipStream and DeflateStream?

There are two basic compression methods that are exposed in the .NET I/O Framework i.e. System.IO namespace : GZIP and DEFLATE. They (Compression methods) are exposed via streams and support both compression and decompression (which ofcourse makes sense!).

Compression Streams in .NET
  • System.IO.Compression.GZipStream
  • System.IO.Compression.DeflateStream
Important Facts

The compression streams in .NET support compression of streams with a maximum size of 4GB. You will have to break your file down if it is larger than 4GB. A drawback of the .NET compression methods is that you cannot compress multiple files into a single archive file, like you may be used to with WinZip or other similar tool. Atleast this is not avaialable out of the box.

Which one to use – GZip or Deflate?

Both these methods use the same compression algorithm (RFC 1952). But if you are going to be interfacing with other applications that require a more standard scheme, you may choose GZip. Deflate generally results in a smaller size as there is no header information unlike GZip. So you may choose this method if you dont foresee the need for interfacing with applications that might require GZip or you dont care about the header information.

Compressing a File

To compress a file you do the following:

    • Create an Input Stream from the input file
Stream inputStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read);
    • Create an output stream using the output file
Stream outputStream = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.Write);
    • Wrap the output stream in a GZipStream or DeflateStream. Use the CompressionMode.Compress
Stream compStream = new GZipStream(outputStream, CompressionMode.Compress);
    • Read the input stream (use the Read or ReadByte method)
byte[] buffer = new byte[inputStream.Length];
int bytesRead = inputStream.Read(buffer, 0, buffer.Length);
    • Write the bytes read to the compression stream
compStream.Write(buffer, 0, buffer.Length);
    • Finally, close all the three streams
finally
{
inputStream.Close();
compStream.Close();
outputStream.Close();
}
Decompressing a File
    • Create an Input Stream from the compressed file
Stream inputStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read);
    • Create an output stream using the output file (i.e. Uncompressed file)
Stream outputStream = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.Write);
    • Wrap the Input stream in a GZipStream or DeflateStream
compStream = new GZipStream(inputStream, CompressionMode.Decompress);
    • Read the input stream (use the Read or ReadByte method)
    • Write the bytes read to the output stream
try
{
	//write to compression stream
	int inByte = compStream.ReadByte();
	while (inByte != -1)
	{
	outputStream.WriteByte((byte)inByte);
	inByte = compStream.ReadByte();
	}
}
    • Finally, close all the three streams
finally
{
	compStream.Close();
	inputStream.Close();
	outputStream.Close();
}
Final Remarks

As you can see, the compression and decompression steps are complimentary and fairly straight forward. I have noticed (and this is my personal experience) that sometimes when you read one byte at a time and write to the compressed stream you actually get a larger file as an output. I am going to be researching why this is. When I find out so will you. But my workaround has been to read the whole stream or chunks of bytes at a time.

In my next post I will talk about Isolated Storage

Cheers!

No comments

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

\\\