Search code examples
delphidelphi-xe8

Delphi XE 8 - how to decompress a gzip file?


I'm using Delphi XE 8 and trying to decompress a gzip file. I've copied the following code straight from the Embarcadero website as an example, but I get "EZDecompressionError with message 'data error'.

procedure DecompressGzip(inFileName : string);
var
  LInput, LOutput: TFileStream;
  LUnZip: TZDecompressionStream;

begin
  { Create the Input, Output, and Decompressed streams. }
  LInput := TFileStream.Create(InFileName, fmOpenRead);
  LOutput := TFileStream.Create(ChangeFileExt(InFileName, 'txt'), fmCreate);
  LUnZip := TZDecompressionStream.Create(LInput);

  { Decompress data. }
  LOutput.CopyFrom(LUnZip, 0);
  { Free the streams. }
  LUnZip.Free;
  LInput.Free;
  LOutput.Free;
end;

An example file I'm trying to decompress is located here: http://ftp.nhc.noaa.gov/atcf/aid_public/


Solution

  • Your code is correct, but you've forgot to enable zlib to detect gzip header (by default, the only data format recognized is zlib format). You have to call TDecompressionStream.Create(source: TStream; WindowBits: Integer) overloaded constructor and specify how deep zlib should look into stream for gzip header:

    procedure TForm2.FormCreate(Sender: TObject);
    var
      FileStream: TFileStream;
      DecompressionStream: TDecompressionStream;
      Strings: TStringList;
    begin
      FileStream := TFileStream.Create('aal012015.dat.gz', fmOpenRead);
    {
         windowBits can also be greater than 15 for optional gzip decoding.  Add
       32 to windowBits to enable zlib and gzip decoding with automatic header
       detection, or add 16 to decode only the gzip format (the zlib format will
       return a Z_DATA_ERROR).
    }
      DecompressionStream := TDecompressionStream.Create(FileStream, 15 + 16);  // 31 bit wide window = gzip only mode
    
      Strings := TStringList.Create;
      Strings.LoadFromStream(DecompressionStream);
    
      ShowMessage(Strings[0]);
    
      { .... }
    end;
    

    For further reference look into zlib manual, also this question might be useful.