我几个小时以来一直在搜索,以使用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(对于我来说是不可接受的)。
答案 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);