Home > C# .NET > C# .NET Tutorial 7: Compressing Streams

C# .NET Tutorial 7: Compressing Streams

By now you have got used to the C# tutorials. If not you can view all of them here. This tutorial will focus on stream classes that support compression of data. In the .NET Framework there are two such streams.

In the I/O system of the .NET Framework that are two method of compressing data: GZIP and DEFLATE. Both these compression algorithms are industry-standard and are limited to compression of uncompressed data up to 4GB. These compression methods are exposed in two streams: GZipStream, and DeflateStream classes.

GZipStream Class and the DeflateStream Class

The functionality of these two classes is identical. The only difference is the compression algorithm that they use. Here are the important properties of these classes:

  • BaseStream – gets the underlying stream.
  • CanRead – determines whether the stream supports reading while decompressing a file.
  • CanWrite – determines whether the stream can be written to.
  • CanTimeout – determines whether the stream can timeout.
  • CanSeek – determines whether the stream supports seeking.
  • Length – this is inherited from the Stream class however do not use it with these classes because it will throw a NotSupportedException
  • Position – this is inherited from the Stream class however do not use it with these classes because it will throw a NotSupportedException
  • ReadTimeout – gets or sets the stream’s time out for read operations.
  • WriteTimeout – gets or sets the stream’s time out for write operations.

The following are the most commonly used methods:

  • Close – closes the streams and any other resources associated with it.
  • Flush – clears any buffers within the stream and forces any changes to be written to the underlying system or device.
  • Read – performs a sequential read of a specified number of bytes and then moves the cursor accordingly.
  • ReadByte – reads a single byte and moves the cursor by one.
  • Write – writes a specified number of bytes of data to the stream and updates the cursor to reflect the new write position.
  • WriteByte – writes a single byte to the stream and updates the position.
  • Seek – Not implemented. It will throw a NotSupportedException.
  • SetLength – Not implemented. It will throw a NotSupportedException.

How to Compress Data with a Compression Stream

Compression streams are a little different than the other streams. Instead of the stream writing to a resource such as a file or memory, the compression streams write to another stream. The compression streams take in data like any other stream. But then it writes it in compressed format to another stream. The following example demonstrates how to compress a file and write a new compressed version.

//first we need to open the file and create a new file for the compressed version
FileStream sourceFile = File.OpenRead(@"C:\data.bak");
FileStream destFile = File.Create(@"C:\data.gzip");

//now we need the compression stream to wrap the outgoing stream
GZipStream compStream = new GZipStream(destFile, CompressionMode.Compress);

//all we need to do now is write from the source file to the compression stream
int aByte = sourceFile.ReadByte();
while (aByte != -1)
{
    compStream.WriteByte((byte)aByte);
    aByte = sourceFile.ReadByte();
}

Note that we never wrote in the destination file. Because we are writing in the compression stream, the compression stream will write the compressed version in the destination file. Also if you want to use the Deflate algorithm all you need to do is change the compression stream to the DeflateStream.

How to Decompress Data with a Compression Stream

Here is the code used for decompression.

//Like before we need to declare a source file and a destination file. But now the source file is the compressed version.
FileStream sourceFile = File.OpenRead(@"C:\data.gzip");
FileStream destFile = File.Create(@"C:\data.bak");

//Now the change comes in the compression stream algorithm. We will wrap the source file and we will used the Decompress mode
GZipStream decompStream = new GZipStream(sourceFile, CompressionMode.Decompress);

//Now we need to read from the compression stream (not the source file) and write to the destination file
int aByte = decompStream.ReadByte();
while (aByte != -1)
{
    destFile.WriteByte((byte)aByte);
    aByte = decompStream.ReadByte();
}

So you now know how to compress and decompress streams. What’s next? In the next tutorial I will show you how to work with isolated storage. With isolated storage, data is always isolated by user and by assembly. Until then enjoy!!

Categories: C# .NET
  1. No comments yet.
  1. No trackbacks yet.