Unzipping .gz files using gzipstream

Aug 12, 2009 at 9:19 AM

Do you have any sample code for unzipping .gz files using gzipstream in VB.Net?

Many thanks

Coordinator
Aug 12, 2009 at 1:08 PM

Imports System
Imports System.IO
Imports Ionic.Zlib

Namespace Ionic.TestsAndTools

Public Class GunZipFile

    Dim WORKING_BUFFER_SIZE As Integer = 2048
    Dim UncompressedFile As String
    Dim CompressedFile As String

    Private Sub DoGunZip()
        Dim working(WORKING_BUFFER_SIZE) as Byte
        dim n As Integer = 1
        Using input As Stream = File.OpenRead(CompressedFile)
            Using decompressor As Stream = new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, True)
                Using output As Stream = File.Create(UncompressedFile)
                    Do
                        n= decompressor.Read(working, 0, working.Length)
                        If n > 0 Then
                            output.Write(working, 0, n)
                        End IF
                    Loop While (n  > 0)
                End Using
            End Using
        End Using
    End Sub
 ...

Aug 20, 2009 at 12:29 PM
Edited Aug 20, 2009 at 1:06 PM

Cheeso

Many thanks for the sample code, it works great with most of the files that I have, but not all. The ones it doesn’t work with are .gz files that contain multiple compressed files. Is there some way that DotNetZip can uncompress these? as, so for, I´ve been unable to find it.

Coordinator
Aug 20, 2009 at 4:17 PM

The GZipStream itself reads in a single entry in GZIP format.  This limitation of the GZipStream class is documented.

Though the GZIP format allows data from multiple files to be concatenated together, this stream handles only a single segment of GZIP format, typically representing a single file.

 To read multiple entries, you'd need to read in the file as a stream, and loop over each entry with a GZipStream.  Something like this:

Private Sub DoGunZip()
    Dim working(WORKING_BUFFER_SIZE) as Byte
    dim n As Integer = 1
    Using input As Stream = File.OpenRead(CompressedFile)
        Do While (input.Length > input.Position)
            Using decompressor As Stream = new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, True)
                Using output As Stream = File.Create(UncompressedFile)
                    Do
                        n= decompressor.Read(working, 0, working.Length)
                        If n > 0 Then
                            output.Write(working, 0, n)
                        End IF
                    Loop While (n  > 0)
                End Using
            End Using
        Loop
    End Using
End Sub

I don't know if this will work, because I don't have a GZ file structured in this way, and I don't know a good way to produce one to do a test.  But it seems like it should work. If you can send me a sample .gz file with multiple entries, I'd be glad to test it.

 

 

Aug 21, 2009 at 9:26 AM

Cheeso

Once again, thanks for your reply. After playing around with various methods I have discovered that the .gz file I have containing multiple entries can actually be decompressed successfully when I treat it as a .zip file. Strangely I have other files from the same source that have the .gz extension but need to be decompressed using the GZipStream.

Out of interest I tried the code sample you sent but couldn’t get it to work, although maybe the above explains that.

Unfortunately I cannot send you a sample GZip file containing multiple files as the only ones I have are a) excessively large and b) subject to Data Protection laws.

Coordinator
Aug 21, 2009 at 9:40 AM

Glad you got it solved. Just FYI, GZIP is not ZIP, they are not interchangeable or compatible.  Sounds like a mis-named file, to me.

Aug 21, 2009 at 9:42 AM

It looks like that to me too but I can’t ask the people who created it. Unfortunately I spent the best part of yesterday treating it as a .GZip file L