Xceed .NET Libraries Documentation
Welcome to Xceed Data Manipulation Compoents for .NET and .NET Standard / Basic Concepts / Zip and streaming capabilities / Streaming compression / Decompressing / Decompressing a GZip file

In This Topic
    Decompressing a GZip file
    In This Topic

    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