delphi - 使用 Delphi 进行 GZip 流压缩(可选使用 tar)

标签 delphi stream gzip zlib deflate

我花了好几个小时在 Delphi 10 中使用流创建有效的 .tar.gz 文件。

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

经过一番搜索,我还找到了仅使用 System.ZLib 解压缩 gzip 数据的示例。 secret 在于 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 header ?),但无法自行创建这样的 header ?无论我尝试什么,我都只能得到一个无法通过 7zip 或 WinRar 打开的文件,因为 header 丢失。

也许它无法工作,因为gzip header 包含校验和,因此在不知道以下数据的情况下不可能写入 header 。怎么解决这个问题呢?编辑:这是错误的,请参阅评论:crc32 在预告片中。

看来,许多其他人也有这个问题 - 我找到并尝试了多种解决方案来添加此 header ,但没有任何效果,并且一切都需要添加长单元(不好但可以接受)甚至 DLL(对我来说 Not Acceptable )。

最佳答案

secret 在于 WindowBits 参数 - 听起来很熟悉? :)

不管你信不信,压缩到 gzip 的工作原理是一样的!我无法在任何地方使用 Google 或 Embarcadero 文档/帮助中找到此内容。但是请看一下 Delphi Tokyo 的 System.ZLib 源代码中的此注释:

Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper. The gzip header will have no file name, no extra data, no comment, no modification time (set to zero), no header crc, and the operating system will be set to 255 (unknown).

它有效:

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);

关于delphi - 使用 Delphi 进行 GZip 流压缩(可选使用 tar),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52815666/

相关文章:

delphi - 如果在回调期间测试连接,Indy OpenSSL 会出现问题

python-2.7 - Python 2.7 中的 Gzip 和编码文件

delphi - 如何使用存储在 TList 中的对象的方法?

c# - 流读取问题

javascript - Node.js - 找到值后读取流,然后关闭

c - 通过 c 中的管道而不是文件将数据数组传递给 gnuplot

express - axios在gzip中不解压获取响应体

gzip - 文件在哪里以及如何被 gzip 压缩?

delphi - 添加到数据库不起作用

delphi - 访问 TForm.Create 上的 TWinControl.Handle