Better
data transmission using Compressed Streams in .Net
As the number
of web-based applications have increased, so also the need for faster
connectivity and more bandwidth. The main reason for this is the data
transmitted over the network is becoming voluminous leading to high traffic.
This finally can result in poor performance of the application and lower
productivity.
To address
this issue, one of the main technologies suggested is the data compression
which can save space and bandwidth to a great extent. .Net supports this
feature by introducing classes that implement this technology.
The .Net framework offers compression and decompression services as a
part of File Input / Output (I/O) system. The two methods of compression
techniques are Gzip and Deflate. Both these methods adopt industry-standard
compression algorithms and free of patent protection. They can compress
a data of maximum size of 4GB.
The only difference in both the methods is that GZip allows using header
information that can be used while decompressing the zip file using the
popular gzip tool. In case of compression and decompression within the
application, it is suggested to use Deflate since the compressed data
is of lesser size due to its lack of header information.
GzipStream and DeflateStream classes
The .Net framework provides two classes called GzipStream and DeflateStream
to implement the lossless compression/decompression feature. Unlike the
other classes that handle streams in file systems, these classes take
in data like any other stream and writes the compressed data into another
stream in the compressed format instead of writing into a file or memory.
Both these classes have properties like the underlying BaseStream, timeout
for read/write operations, option to support seeking, etc.
They also have methods to perform a sequential read (single or specified
number of bytes), write bytes (single or specified number), etc. To use
these classes in the code, the namespace, System.IO.Compression has to
be included.
The compression format includes a cyclic redundancy check value for checking
data corruption. Since the compression is executed by reading the data
on byte-by-byte basis, it is not possible to perform multiple passes to
determine best method for compressing entire files or large blocks of
data. It is suggested to use the compression for uncompressed data and
not for data that is already compressed. It is very important for the
user to have sufficient access rights to operate on the file system before
executing the code.
Following are the steps to be executed for compressing stream:
Create two FileStream objects, one for the source and other for
destination.
Create the instance of GzipStream class by specifying the destination
file and option to express compression as second parameter.
Traverse the source file by reading byte by byte and pass it to
the GZipStream object for writing the compressed form in it. The destination
stream which is in compressed form thus updates the destination file.
It is to be noted here that the destination file is not directly updated.
Close both files.
//Following code (in C#) illustrates the above compression logic
FileStream sourceFileObj = File.OpenRead(source_file_Name);
FileStream desFileObj = File.Create(destination_file_Name);
GZipStream compressedStreamObj = new GZipStream(desFileObj, CompressionMode.Compress);
int aByte = sourceFileObj.ReadByte();
while(aByte != -1) {
compressedStreamObj.WriteByte((byte)aByte);
aByte = sourceFileObj.ReadByte();
}
Following are the steps to be executed for decompressing stream:
Create two FileStream objects, one for the source and other for
destination.
Create the instance of GzipStream class by specifying the source
file and option to express decompression as second parameter.
Traverse the compressed stream (fetched from the source file) by
reading byte by byte and write the decompressed form directly into the
destination file.
Close both files.
//The code (in C#) below illustrates the above compression logic
FileStream sourceFileObj = File.OpenRead(source_file_Name);
FileStream desFileObj = File.Create (destination_file_Name);
GZipStream compressedStreamObj = new GZipStream(sourceFileObj, CompressionMode.DeCompress);
int aByte = compressedStreamObj.ReadByte();
while(aByte != -1) {
desFileObj.WriteByte((byte)aByte);
aByte = compressedStreamObj.ReadByte();
}
Note:
In both methods of compression and decompression, the compression
stream is meant to wrap the stream that contains (or will contain) compressed
data. In case compression is executed, the wrapped stream will be compressed
data that will be read as input. If it is decompression, the wrapped data
will be the compressed data that will be written as output.
The above lines of code (for both compression and decompression)
remain the same when DeflateStream class is used except when the creation
of the compressed stream objects where DeflateStream has to be used instead
of GZipStream.
Both the sample code needs to include the namespace, System.IO.Compression
(by adding 'using' statement) in the top.