使用Delphi压缩GZip流(可选使用tar)

时间:2018-10-15 11:23:53

标签: delphi stream gzip zlib deflate

我几个小时以来一直在搜索,以使用Delphi 10中的流创建有效的.tar.gz文件。

我能够使用LibTar解决tarball部分,效果很好。

经过一些搜索,我还找到了仅使用System.ZLib解压缩gzip数据的示例。秘密在于WindowBits参数:

// 31 bit wide window = gzip only mode
DecompStream:= TZDecompressionStream.Create(SourceStream, 15 + 16);
TarStream:= TTarArchive.Create(DecompStream);
TarStream.Reset;
while TarStream.FindNext(DirRec) do {...} TarStream.ReadFile(TargetStream);

太好了!但是,System.ZLib真的有可能解压缩gzip吗(我猜只是通过+16忽略了gzip标头?),却无法独自创建这样的标头吗?不管尝试什么,我都只会得到7zip或WinRar无法打开的文件,因为缺少标头。

由于gzip标头包含校验和,因此可能无法正常工作,因此在不了解以下数据的情况下无法编写标头。如何解决呢?编辑:这是错误的,请参阅注释:crc32在预告片中。

看来,许多其他人也有这个问题-我发现并尝试了多种解决方案来添加此标头,但没有任何实际效果,并且所有操作都需要添加长单元(不是很好,但可以接受)甚至是DLL(对于我来说是不可接受的)。

1 个答案:

答案 0 :(得分:1)

秘密在于WindowBits参数-听起来很熟悉吗? :)

信不信由你,将其压缩为gzip的工作方式相同!使用Google或在Embarcadero文档/帮助中,我找不到任何地方。但是,请在Delphi Tokyo的System.ZLib来源中查看以下评论​​:

  

在windowBits中添加16以编写一个简单的gzip标头,并   尾随压缩数据而不是zlib包装器。的   gzip标头将没有文件名,没有额外的数据,没有注释,没有   修改时间(设置为零),无标头crc,并且运行   系统将设置为255(未知)。

有效:

TargetStream:= TFileStream.Create(TargetFilename, fmCreate);
CompressStream:= TZCompressionStream.Create(TargetStream, zcDefault, 15 + 16);
TarStream:= TTarWriter.Create(CompressStream);
TarStream.AddStream(SourceStream1, SourceFilename1, Now);
TarStream.AddString(SourceString2, SourceFilename2, Now);