Delphi XE 8 - 如何解压缩 gzip 文件?
Delphi XE 8 - how to decompress a gzip file?
我正在使用 Delphi XE 8 并尝试解压缩 gzip 文件。
作为示例,我直接从 Embarcadero 网站复制了以下代码,但我收到“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;
我尝试解压的示例文件位于此处:
http://ftp.nhc.noaa.gov/atcf/aid_public/
您正在尝试将数据视为经过 zlib 压缩的数据。然而,这与 gzip 压缩数据不兼容。虽然两种格式使用相同的内部压缩算法,但它们具有不同的 headers.
要解压缩 gzip,请参考以下问题:How to decode gzip data? Remy 的回答解释了如何使用 Indy 的 TIdCompressorZLib
来解压缩 gzip 数据。
您的代码是正确的,但您忘记启用 zlib
来检测 gzip
header(默认情况下,唯一可识别的数据格式是 zlib 格式)。您必须调用 TDecompressionStream.Create(source: TStream; WindowBits: Integer)
重载构造函数并指定 zlib
应该在流中查看 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;
如需进一步参考,请查看 zlib
manual, also this question 可能会有用。
我正在使用 Delphi XE 8 并尝试解压缩 gzip 文件。 作为示例,我直接从 Embarcadero 网站复制了以下代码,但我收到“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;
我尝试解压的示例文件位于此处: http://ftp.nhc.noaa.gov/atcf/aid_public/
您正在尝试将数据视为经过 zlib 压缩的数据。然而,这与 gzip 压缩数据不兼容。虽然两种格式使用相同的内部压缩算法,但它们具有不同的 headers.
要解压缩 gzip,请参考以下问题:How to decode gzip data? Remy 的回答解释了如何使用 Indy 的 TIdCompressorZLib
来解压缩 gzip 数据。
您的代码是正确的,但您忘记启用 zlib
来检测 gzip
header(默认情况下,唯一可识别的数据格式是 zlib 格式)。您必须调用 TDecompressionStream.Create(source: TStream; WindowBits: Integer)
重载构造函数并指定 zlib
应该在流中查看 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;
如需进一步参考,请查看 zlib
manual, also this question 可能会有用。