1

我正在使用 Delphi XE 8 并尝试解压缩 gzip 文件。作为示例,我直接从 Embarcadero 网站复制了以下代码,但我收到“EZDecompressionError 和消息‘数据错误’。

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;

我尝试解压缩的示例文件位于此处: http: //ftp.nhc.noaa.gov/atcf/aid_public/

4

2 回答 2

4

您的代码是正确的,但您忘记启用zlib检测gzip标头(默认情况下,唯一识别的数据格式是 zlib 格式)。您必须调用TDecompressionStream.Create(source: TStream; WindowBits: Integer)重载的构造函数并指定zlib应在流中查看gzip标头的深度:

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;

为了进一步参考zlib手册这个问题也可能有用。

于 2015-07-05T00:26:48.877 回答
0

您正试图将数据视为经过 zlib 压缩。但是,这与 gzip 压缩数据不兼容。尽管两种格式都使用相同的内部压缩算法,但它们具有不同的标头。

要解压缩 gzip,我建议您参考这个问题:如何解码 gzip 数据?Remy's answer there解释了如何使用TIdCompressorZLib来自Indy的解压缩gzip数据。

于 2015-07-04T14:15:17.390 回答