我用Delphi10中的streams来创建一个有效的.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 (我猜只是忽略gzip头+16?),但不能自己创建这样的头?不管我怎么尝试,我只能得到一个不能被7zip或WinRar打开的文件,因为标题丢失了。
也许它就是不能工作,因为gzip头文件包含一个校验和,所以在不知道以下数据的情况下不可能写入头文件。如何解决这个问题?编辑:这是错误的,请参阅注释: crc32在预告片中。
似乎,其他许多人也有这个问题-我找到并尝试了多种解决方案来添加这个头文件,但都没有真正起作用,所有的东西都需要添加长单元(不是很好,但可以接受)甚至DLL(对我来说不能接受)。
发布于 2018-10-15 19:23:53
秘诀在于WindowBits
参数-听起来熟悉吗?:)
信不信由你,压缩成gzip的方式是一样的!我在使用Google或在Embarcadero文档/帮助中都找不到它。但看看德尔福东京的System.ZLib
源中的这条评论:
将16添加到windowBits中,以便在压缩数据周围编写一个简单的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);
https://stackoverflow.com/questions/52815666
复制相似问题