Click here to Skip to main content
15,887,485 members
Articles / Programming Languages / C#

Stream Compression - System.IO.Compression Library – Usability Review.

Rate me:
Please Sign up or sign in to vote.
1.00/5 (1 vote)
4 Aug 2011CPOL4 min read 6.5K   2  
CodeProject >Couple of weeks ago I was working along with the architect, designinga feature that we needed to support in our product, as part of the requirements,the user had to download a report (which can be pretty large)so we were discussing what library we should use forcompressing th

Couple of weeks ago I was working along with the architect, designing a feature that we needed to support in our product, as part of the requirements, the user had to download a report (which can be pretty large) so we were discussing what library we should use for compressing the report.

He recommended using an open source utility; which initially seemed odd to me as .Net framework already has a compression feature plus there’s a whole process we needed to go thru to have this open source utility approved so it can be added to the project. I asked him to reconsider his decision, but he seemed pretty sure that’s the right way to go; he said something, that kind of got me thinking, he said that “the compression library is difficult to use” based on his experience, developers find it hard to use.

Because we had a deadline to meet, and without further discussion of this. we simply took his recommendation and moved on.

A look inside System.IO.Compression

The first thing that comes to my mind, at least when using compression API’s or any library in the Net Framework, is that somewhere there’s a method or class named as Compress/Decompress, something that represents the action you’re a looking for; something as simple as passing in the name of the algorithm, the stream and the file path for example. In Fact, the Net framework does a really good job handling feature usability.

Most of their API’s are based on that premise.

Let’s take a look inside the Compression library to see if we can figured out why some people may find it hard to use.

image

Remember I said that my first guess is that there’s probably a class or method named Compress/Decompress? Well, there are only 3 members available for public use: CompressionMode, DeflateStream, GzipStream. None of these members points me to the right direction as to how to use the library.

Just like any other developer I feel like not doing too much research. mmm! Let’s see, perhaps if I go inside one of the public members, there might be a chance we can determine the logical operation of the compression library.

GZipStream: I didn’t find a method named compress or decompress but I found that the class inherits from Stream and further extends its functionality, if you look inside the overloaded class constructor, this is where most of its functionality takes place, it seems to be a compression type implementation:

public GZipStream(Stream stream, CompressionMode mode, bool leaveOpen)  {

    this.deflateStream = new DeflateStream(
    stream, mode, leaveOpen);    
    if (mode == CompressionMode.Compress) 
    {
     IFileFormatWriter gZipFormatter = new GZipFormatter(); 
      this.deflateStream.SetFileFormatWriter(gZipFormatter);
      return; 
    }
   IFileFormatReader gZipDecoder = new GZipDecoder(); 
    this.deflateStream.SetFileFormatReader(gZipDecoder);  }

DeflateStream: Same thing here. The overloaded class constructor looks like:

public DeflateStream(Stream stream, 
    CompressionMode mode, bool leaveOpen)  {

    this._stream = stream;
    this._mode = mode; 
    this._leaveOpen = leaveOpen;
    if (this._stream == null) 
    {
     throw new ArgumentNullException("stream"); 
    }
   switch (this._mode) 
    {
     case CompressionMode.Decompress: 
      {
       if (!this._stream.CanRead) 
        {
         throw new ArgumentException(SR.GetString(
             "NotReadableStream"),"stream"); 
        }
       this.inflater = new Inflater(); 
        this.m_CallBack = new AsyncCallback(this.ReadCallback);      }

      case CompressionMode.Compress:      {

        if (!this._stream.CanWrite)        {

          throw new ArgumentException(SR.GetString(
          "NotWriteableStream"),"stream");        }

        this.deflater = new Deflater();
        this.m_AsyncWriterDelegate
= new AsyncWriteDelegate(this.InternalWrite); 
        this.m_CallBack
= new AsyncCallback(this.WriteCallback);      }

    }
   throw new ArgumentException(SR.GetString("ArgumentOutOfRange_Enum"),"mode"); 
    this.buffer = new byte[4096];  }

The compressionMode is basically an enum:

public enum CompressionMode {

  Compress,
 Decompress

}

Although I didn’t find what I was expecting, I did found two features implemented, which basically compresses/decompresses a stream at the moment you instantiate each class in the overloaded constructor method. At this point I now have an idea, I can write a class that can use either one of these implementations. But wait, what if the compress/decompress class or method I’m looking for, is implemented somewhere else, and I ‘m looking in the wrong place?

Okay I have no choice but to dig into MSDN documentation to find how to use this class, I don’t want to write duplicated code, if there a class that already takes care of what I’m looking for, I want to use it. I went over the samples in MSDN online documentation provided by Microsoft for each implementation but it wasn’t as simple as I expected, you know, implementing it without having to do research.

image

After looking at both sample implementations on the MSDN, I’ve basically concluded the following:

  • I don’t think there’s an utility class with a method named Compress/Decompress, that I can

Pass along the algorithm I want to use, the stream or the file name.

  • It seems that the main functionality resides on each implementation( DeflateStream, GzipStream)

In their overloaded constructor method. I can take advantage of this and create an utility class myself that let’s you chose the compression class, and can take at least one parameter to keep it simple. I guess Shane, our software architect wasn’t so wrong after all, is not easy to use this library.

In a next post (this is one is getting too big), I’ll be writing a class utility that you can use in your projects.

Features:

. Flexible enough to support DeflateStream, GzipStream or any other future implementations (if the API doesn’t change)

You can use your own compression class implementation as long as it follows the same pattern. Minimum maintenance changes require, this is an utility class after all, so we want to keep it simple. It’ll have for sure, method names such as Compress/Decompress ...

.Easy to use.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --