Unzipping compressed files using GZipStream

This tutorial will teach you how to unzip compressed files using the new namespace of .NET 2.0, System.IO.Compression, which contains the GZipStream class that allows us to decompress compressed ZIP files.

Compressing (zipping) In the previous tutorial entitled Zipping files using GZipStream we reviewed how to compress files using the System.IO.Compression namespace, and we also learned that the GZipStream class of this namespace has some limitations. If you haven’t read that tutorial, I suggest that you read it, and among other things you will learn that we can’t compress multiple files into a single archive and/or give them each a file name like you are used to when using popular tools such as WinRAR or WinZIP. Details on why this isn’t possible and what workaround is available are in that tutorial.

This means we also can’t decompress ZIP archives that have multiple files or a filename header defined in them. Basically it is recommended that you only decompress files that were compressed using the GZipStream. If you’re looking to build an application similar to WinRAR or WinZIP, you would probably be better with a 3rd party class library that has more functionality or – if you have enough experience – extending the GZipStream class to include the missing functionality.

Decompressing (unzipping, sample application) Start by creating a new Windows application project into Visual Studio 2005. Add to the form a TextBox and two Buttons. The TextBox is entitled txtPath and it will hold the path to the file to decompress. The Buttons are entitled btnBrowse and btnDecompress. The first one will show an OpenFileDialog for picking a ZIP file to decompress, and the second one – btnDecompress – will show a SaveFileDialog followed by the actual decompressing and saving process. Finally, make sure you add an OpenFileDialog and SaveFileDialog to our application and name them openFile and saveFile.

Among the already existent namespaces, add the following two at the top of the class file:

using System.IO;

using System.IO.Compression;

Now double click btnBrowse and its Click event will be created. Inside it use the following code that displays the OpenFileDialog and allows the user to pick a file to decompress:

// Show the dialog where the user chooses the file to decompress

if (openFile.ShowDialog() == DialogResult.OK)

{

        txtPath.Text = openFile.FileName;

}

Now double click the btnDecompress button so that you get to its click event and inside it use the following code which will take the compressed file and try to decompress it.

// If the user has selected a path where to put the decompressed file

if (saveFile.ShowDialog() == DialogResult.OK)

{

    // Bytes array in which we're going to store the actual file to be decompressed

    byte[] bufferWrite;

    // Will open the file to be decompressed

    FileStream fsSource;

    // Will write the new decompressed file

    FileStream fsDest;

    // To hold the compressed file

    GZipStream gzDecompressed;

    fsSource = new FileStream(txtPath.Text, FileMode.Open, FileAccess.Read, FileShare.Read);

    // Will hold the compressed stream created from the destination stream

    gzDecompressed = new GZipStream(fsSource, CompressionMode.Decompress, true);

 

    // Retrieve the size of the file from the compressed archive's footer

    bufferWrite = new byte[4];

    fsSource.Position = (int)fsSource.Length - 4;

    // Write the first 4 bytes of data from the compressed file into the buffer

    fsSource.Read(bufferWrite, 0, 4);

    // Set the position back at the start

    fsSource.Position = 0;

    int bufferLength = BitConverter.ToInt32(bufferWrite, 0);

 

    byte[] buffer = new byte[bufferLength + 100];

    int readOffset = 0;

    int totalBytes = 0;

 

    // Loop through the compressed stream and put it into the buffer

    while (true)

    {

        int bytesRead = gzDecompressed.Read(buffer, readOffset, 100);

 

        // If we reached the end of the data

        if (bytesRead == 0)

            break;

 

        readOffset += bytesRead;

        totalBytes += bytesRead;

    }

 

    // Write the content of the buffer to the destination stream (file)

    fsDest = new FileStream(saveFile.FileName, FileMode.Create);

    fsDest.Write(buffer, 0, totalBytes);

 

    // Close the streams

    fsSource.Close();

    gzDecompressed.Close();

    fsDest.Close();

}

Try to decompress a ZIP archive created using WinZIP or a similar application, and it should come as no suprise that the application we built here won’t work for the reasons mentioned at the beginning of the tutorial. If you try compressing the file using the application we built in the previous tutorial the decompressing is guaranteed to work.

Nathan Pakovskie is an esteemed senior developer and educator in the tech community, best known for his contributions to Geekpedia.com. With a passion for coding and a knack for simplifying complex tech concepts, Nathan has authored several popular tutorials on C# programming, ranging from basic operations to advanced coding techniques. His articles, often characterized by clarity and precision, serve as invaluable resources for both novice and experienced programmers. Beyond his technical expertise, Nathan is an advocate for continuous learning and enjoys exploring emerging technologies in AI and software development. When he’s not coding or writing, Nathan engages in mentoring upcoming developers, emphasizing the importance of both technical skills and creative problem-solving in the ever-evolving world of technology. Specialties: C# Programming, Technical Writing, Software Development, AI Technologies, Educational Outreach

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top