Xceed .NET Libraries Documentation
Decompressing a GZip file

Welcome to Xceed .NET, .NET Standard and Xamarin Libraries! > Basic Concepts > Zip and streaming capabilities > Streaming compression > Decompressing > Decompressing a GZip file

This topic demonstrates how to decompress a GZip file (.gz). Although Xceed's streaming compression component supports GZip files, it does not support tar files. 

Jump to the Creating a GZip file topic to learn how to create a GZip file.

Basic steps

To decompress a GZip file, the following steps must be taken:

  1. Create a FileStream around the GZip file. 

  2. Create a GZipCompressedStream around the FileStream. 

  3. Create the destination stream to which the decompressed data will be written. For the purposes of this example, our destination stream will be another FileStream. 

  4. Read the data from the source FileStream. Creating the GZipCompressedStream around the source FileStream means that the data is decompressed as it is read from the source FileStream. 

  5. Write the decompressed data to the destination FileStream.

 Demonstration 1: Typical GZip file

The following example demonstrates how to decompress a GZip file and write the decompressed contents to a FileStream.

using System;

using System.IO;



using Xceed.Compression;

using Xceed.Compression.Formats;



namespace DocumentationExamples.GZip

{

  class GZipDecompressExample

  {

    static void Example()

    {

      // Open a file that contains GZip data for reading

      FileStream source = new FileStream( "SomeGZipFile.dat.gz", FileMode.Open );



      /* The GZip format has a header that contains meta data like a filename, modified date, etc

       * In this example, we will try to use it. We will use a flavor of the constructor that takes

       * a 'readHeader' parameter and pass 'true' so that the constructor reads the GZip

       * header immediately so we can use the values in it to build our output filename. */



      // Wrap the source stream with a GZipCompressedStream

      using( GZipCompressedStream gzip = new GZipCompressedStream( source, CompressionLevel.Normal, true ) )

      {

        /* Because we used the value 'true' in the 'readHeader' parameter, GZipCompressedStream has read 

         * the meta data header. We will now use the values to build a filename for output */



        string filename = gzip.Header.FileName;



        /* If the header does not contain a filename, you will need to provide one ourselves */

        if( String.IsNullOrEmpty( filename ) )

        {

          filename = "SomeGZipFile.dat";

        }



        // Create the destination file

        using( FileStream destination = new FileStream( filename, FileMode.Create ) )

        {

          // Create a 32k buffer

          byte[] buffer = new byte[ 32 * 1024 ];

          int read = 0;



          // Read from the GZip compressed stream while there is data to read

          while( ( read = gzip.Read( buffer, 0, buffer.Length ) ) > 0 )

          {

            // Write the uncompressed data to the destination

            destination.Write( buffer, 0, read );

          }

        }

      }

    }

  }

}
Imports Microsoft.VisualBasic

Imports System

Imports System.IO



Imports Xceed.Compression

Imports Xceed.Compression.Formats



Namespace DocumentationExamples.GZip

  Friend Class GZipDecompressExample

    Private Shared Sub Example()

      ' Open a file that contains GZip data for reading

      Dim source As New FileStream("SomeGZipFile.dat.gz", FileMode.Open)



'       The GZip format has a header that contains meta data like a filename, modified date, etc

'       * In this example, we will try to use it. We will use a flavor of the constructor that takes

'       * a 'readHeader' parameter and pass 'true' so that the constructor reads the GZip

'       * header immediately so we can use the values in it to build our output filename. 



      ' Wrap the source stream with a GZipCompressedStream

      Using gzip As New GZipCompressedStream(source, CompressionLevel.Normal, True)

'         Because we used the value 'true' in the 'readHeader' parameter, GZipCompressedStream has read

'         * the meta data header. We will now use the values to build a filename for output 



        Dim filename As String = gzip.Header.FileName



        ' If the header does not contain a filename, you will need to provide one ourselves 

        If String.IsNullOrEmpty(filename) Then

          filename = "SomeGZipFile.dat"

        End If



        ' Create the destination file

        Using destination As New FileStream(filename, FileMode.Create)

          ' Create a 32k buffer

          Dim buffer(32 * 1024 - 1) As Byte

          Dim read As Integer = 0



          ' Read from the GZip compressed stream while there is data to read

          read = gzip.Read(buffer, 0, buffer.Length)

          Do While read > 0

            ' Write the uncompressed data to the destination

            destination.Write(buffer, 0, read)

            read = gzip.Read(buffer, 0, buffer.Length)

          Loop

        End Using

      End Using

    End Sub

  End Class

End Namespace
 Demonstration 2: GZip file with multiple segments

The following example demonstrates how to decompress a GZip file that contains multiple segments that need to be concatenated into a single uncompressed destination %System.IO.Stream%.

Typically, GZip is used to compress a single "stream". However, the file format allows for multiple streams to be archived in a single GZip file. These multiple streams can refer to different files but, the streams are often just segments of a single file that are meant to be concatenated into a single uncompressed file.

The GZip file format contains no field or flag that clearly indicates how the multiple streams are to be handled. Typically, they are meant to be concatenated into a single destination.

The default behavior of GZipCompressedStream is to process the first segment only and stop. This is because most GZip archives only contain one segment. However, it is possible to make GZipCompressedStream process all the segments in an archive and concatenate them into the destination stream.

To enable the feature, use the GZipCompressedStream constructor flavor that takes the 'concatenateSegments' parameter and use the 'true' value. There is no change in the actual processing of the archive. Internally, each time the end of a segment is reached, GZipCompressedStream starts decompressing the next one until a GZip header cannot be found.

using System;

using System.IO;



using Xceed.FileSystem;

using Xceed.Compression.Formats;



namespace DocumentationExamples.GZip

{

  class GZipCompressedStreamConcatenatedExample1

  {

    static void Example()

    {

      // Select a GZip file

      AbstractFile gzipFile = new DiskFile( "MyFile.dat.gz" );



      // Select a destination file

      AbstractFile destinationFile = new DiskFile( "MyFile.dat" );



      // If the destination file already exists

      if( destinationFile.Exists )

      {

        // Delete it

        destinationFile.Delete();

      }



      // Open a stream of the GZip file for reading

      using( Stream sourceStream = gzipFile.OpenRead() )

      {

        // Create the destination file and get a stream for writing

        using( Stream destinationStream = destinationFile.CreateWrite() )

        {

          /* We want all segments in the archive to be decompressed and concatenated to the

           * destination. To enable the feature, we need to use the constructor flavor that

           * takes the 'concatenateSegments' parameter and use the 'true' value.

           * 

           * There is no change in the actual processing of the archive. Internally,

           * each time the end of a segment is reached, GZipCompressedStream starts

           * decompressing the next one until a GZip header cannot be found. */



          // Wrap the GZip file stream around a GZipCompressedStream that concatenates segments

          using( GZipCompressedStream compressedStream = new GZipCompressedStream( sourceStream, true ) )

          {

            // Create a 64k buffer

            byte[] buffer = new byte[ 64 * 1024 ];



            int read;



            // Read data from the source file, decompressing it

            while( ( read = compressedStream.Read( buffer, 0, buffer.Length ) ) > 0 )

            {

              // Write it to the destination stream

              destinationStream.Write( buffer, 0, read );

            }

          }

        }

      }

    }

  }

}
Imports Microsoft.VisualBasic

Imports System

Imports System.IO



Imports Xceed.FileSystem

Imports Xceed.Compression.Formats



Namespace DocumentationExamples.GZip

  Friend Class GZipCompressedStreamConcatenatedExample1

    Private Shared Sub Example()

      ' Select a GZip file

      Dim gzipFile As AbstractFile = New DiskFile("MyFile.dat.gz")



      ' Select a destination file

      Dim destinationFile As AbstractFile = New DiskFile("MyFile.dat")



      ' If the destination file already exists

      If destinationFile.Exists Then

        ' Delete it

        destinationFile.Delete()

      End If



      ' Open a stream of the GZip file for reading

      Using sourceStream As Stream = gzipFile.OpenRead()

        ' Create the destination file and get a stream for writing

        Using destinationStream As Stream = destinationFile.CreateWrite()

'           We want all segments in the archive to be decompressed and concatenated to the

'           * destination. To enable the feature, we need to use the constructor flavor that

'           * takes the 'concatenateSegments' parameter and use the 'true' value.

'           * 

'           * There is no change in the actual processing of the archive. Internally,

'           * each time the end of a segment is reached, GZipCompressedStream starts

'           * decompressing the next one until a GZip header cannot be found. 



          ' Wrap the GZip file stream around a GZipCompressedStream that concatenates segments

          Using compressedStream As New GZipCompressedStream(sourceStream, True)

            ' Create a 64k buffer

            Dim buffer(64 * 1024 - 1) As Byte



            Dim read As Integer



            ' Read data from the source file, decompressing it

            read = compressedStream.Read(buffer, 0, buffer.Length)

            Do While read > 0

              ' Write it to the destination stream

              destinationStream.Write(buffer, 0, read)

              read = compressedStream.Read(buffer, 0, buffer.Length)

            Loop

          End Using

        End Using

      End Using

    End Sub

  End Class

End Namespace