Click here to Skip to main content
15,884,099 members
Articles / Programming Languages / C#
Tip/Trick

.NET ZLib Implementation

Rate me:
Please Sign up or sign in to vote.
4.91/5 (13 votes)
16 Feb 2018CPOL1 min read 51.6K   2.8K   28   7
Zlib compress / decompress implementation using .NET 4.5.1, with no external DLLs

Introduction

Some weeks ago, I discovered that Microsoft .NET 4.5 supports the Deflate version used in ZLib, and I decided to develop an implementation using only the .NET Framework.

This library has the basic Zlib functions, read and write, and supports the 3 .NET compression levels:

  1. Faster
  2. NoCompression
  3. Optimal

Inside the Code

My ZLib implementation has 3 classes:

  1. ZLibStream.cs
  2. ZLibHeader.cs
  3. Adler32.cs

ZlibStream

This class contains the I/O functions to correctly read or write the ZLib stream. Also, it has the control to determine if it's a supported ZLib stream or not.

ZLibHeader

The ZlibHeader class has the functions for encode or decode the ZLib header.

Adler32

This class has the functions for check the hash in Adler32. The result determines if the stream is correct or not.

How to Encode or Decode a ZLib Header

If you wish to encode a new ZLib header and get the correct 2 first bytes, you need to create a new instance of ZLibHeader. Then, you can set the properties as you want and call the function EncodeZlibHeader. This function will return the 2 bytes of the header.

C#
private void GetZLibHeader()
{
    byte[] bytesHeader;

    //Create a new instance of ZLibHeader
    ZLibHeader header = new ZLibHeader();

    //Set the properties
    header.CompressionMethod = 8; //Deflate
    header.CompressionInfo = 7;

    header.FDict = false; //without dictionary. Note: This library doesn't support dictionary
    switch (this.mCompressionLevel)
    {
        case CompressionLevel.NoCompression:
            {
                header.FLevel = FLevel.Faster;
                break;
            }
        case CompressionLevel.Fastest:
            {
                header.FLevel = FLevel.Default;
                break;
            }
        case CompressionLevel.Optimal:
            {
                header.FLevel = FLevel.Optimal;
                break;
            }
    }

    bytesHeader = header.EncodeZlibHeader();
.
.
.
}

To decode is more easy, ZLibHeader has a static property that receives the 2 bytes of the header. The function will return an instance of ZLibHeader with all header information.

Using the Code for Compress or Decompress

The use of this library is very similar to using GZipStream. The only thing you need is to create a new instance of ZLIBStream, and read or write the wished stream.

C#
//
// File compression
//
Using System.IO.Compression;
Using ZLib;

.
.
.

    OpenFileDialog dlgOpen = new OpenFileDialog();
    CompressionLevel level = CompressionLevel.Optimal;

    if (dlgOpen.ShowDialog() == DialogResult.OK) 
    {
        using (FileStream fsSource = new FileStream(dlgOpen.FileName, FileMode.Open, FileAccess.Read))
        {
            using (FileStream fsTarget = new FileStream(dlgOpen.FileName + ".zlib", 
                   FileMode.Create, FileAccess.Write))
            {
                using (ZLIBStream zs = new ZLIBStream(fsTarget, level, true))
                {
                    int bytesLeidos = 0;
                    byte[] buffer = new byte[1024];

                    while ((bytesLeidos = fsSource.Read(buffer, 0, buffer.Length)) > 0) 
                    {
                        zs.Write(buffer, 0,bytesLeidos);                        
                    }
                }
            }
        }            
    }
C#
//
// File decompression
//
Using System.IO.Compression;
Using ZLib;

.
.
.

OpenFileDialog dlgOpen = new OpenFileDialog();

if (dlgOpen.ShowDialog() == DialogResult.OK)
{ 
    using (FileStream fsSource = new FileStream(dlgOpen.FileName, FileMode.Open, FileAccess.Read))
    {
        using (ZLIBStream zs = new ZLIBStream(fsSource, CompressionMode.Decompress, true))
        {
            using (FileStream fsTarget = new FileStream(dlgOpen.FileName + ".txt", 
                   FileMode.Create, FileAccess.Write))
            {
                int bytesLeidos = 0;
                byte[] buffer = new byte[1024];

                while ((bytesLeidos = zs.Read(buffer, 0, buffer.Length)) > 0)
                {
                    fsTarget.Write(buffer, 0, bytesLeidos);
                }

            }
        }
    }            
}

History

  • 17/02/2018: Improved some functions with bitwise operations
  • 16/02/2015: Initial release

License

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


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

Comments and Discussions

 
QuestionBad compression data Pin
Member 1358031116-Jun-23 3:40
Member 1358031116-Jun-23 3:40 
PraiseMy vote of 5 Pin
Jiří Skála27-Feb-18 21:37
Jiří Skála27-Feb-18 21:37 
PraiseCool Pin
Member 1368383618-Feb-18 2:28
Member 1368383618-Feb-18 2:28 
QuestionCool Pin
jfriedman17-Feb-15 5:27
jfriedman17-Feb-15 5:27 
Consider an additional part about compression itself and possibly as well a way to expand the concept and use different algorithms.
QuestionGZipStream Pin
Member 167816-Feb-15 22:56
Member 167816-Feb-15 22:56 
AnswerRe: GZipStream Pin
Alberto M.17-Feb-15 2:16
Alberto M.17-Feb-15 2:16 
GeneralMy vote of 5 Pin
Franc Morales16-Feb-15 22:37
Franc Morales16-Feb-15 22:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.