Click here to Skip to main content
14,241,320 members

.NET ZLib Implementation

Rate this:
4.91 (11 votes)
Please Sign up or sign in to vote.
4.91 (11 votes)
16 Feb 2018CPOL
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.

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.

//
// 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);                        
                    }
                }
            }
        }            
    }
//
// 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)

Share

About the Author

Alberto M.
Software Developer
Spain Spain
No Biography provided

Comments and Discussions

 
PraiseMy vote of 5 Pin
Jiri Skala27-Feb-18 21:37
memberJiri Skala27-Feb-18 21:37 
PraiseCool Pin
Member 1368383618-Feb-18 2:28
memberMember 1368383618-Feb-18 2:28 
QuestionCool Pin
jfriedman17-Feb-15 5:27
professionaljfriedman17-Feb-15 5:27 
QuestionGZipStream Pin
Member 167816-Feb-15 22:56
memberMember 167816-Feb-15 22:56 
AnswerRe: GZipStream Pin
Alberto M.17-Feb-15 2:16
memberAlberto M.17-Feb-15 2:16 
GeneralMy vote of 5 Pin
Franc Morales16-Feb-15 22:37
memberFranc 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.

Tip/Trick
Posted 16 Feb 2015

Tagged as

Stats

32.3K views
1.7K downloads
26 bookmarked