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