You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi中如何使用Zlib以windowbits=-15进行Raw Deflate压缩?

Raw Deflate压缩问题:压缩流为空的解决方法

我需要以Raw Deflate方式压缩数据,且将Windowbits设置为-15。外部方以此方式压缩的文件可通过外部工具解压,我使用windowbits=-15的解压代码可正常工作:

procedure DeCompressStreamBits(Src: TMemoryStream; bits: Integer);
Var z: TZDeCompressionStream;
    mem: TMemoryStream;
begin
  Src.Seek32(0, soBeginning);
  z := TZDecompressionStream.Create(Src, bits);
  mem := TMemoryStream.Create;
  z.Seek32(0, soBeginning);
  mem.CopyFrom(z, z.Size);
  mem.Seek32(0, soBeginning);
  Src.Clear;
  Src.SetSize(mem.Size);
  Src.Write(mem.Memory^, mem.Size);
  mem.Free;
  z.Free;
end;

但我编写的压缩代码运行后目标流为空,无法生成可被该工具解压的文件,请问正确的实现方式是什么?

原压缩代码:

procedure CompressStreamBits(Src: TMemoryStream; bits: Integer);
Var z: TZCompressionStream;
    mem: TMemoryStream;
begin
  mem := TMemoryStream.Create;
  z := TZCompressionStream.Create(mem, zcFastest, bits);
  Src.Seek32(0, soBeginning);
  z.CopyFrom(Src, Src.Size);
  mem.Seek32(0, soBeginning);
  Src.Clear;
  Src.SetSize(mem.Size);
  Src.Write(mem.Memory^, mem.Size);
  mem.Free;
  z.Free;
end;

问题原因与修正方案

问题核心是TZCompressionStream在完成数据写入后,必须先释放压缩流,才能确保所有压缩数据(包括收尾的校验数据)都被写入到目标内存流。原代码中先操作mem流再释放z,此时压缩流尚未完成最终的数据输出,导致mem流为空或不完整。

修正后的压缩代码:

procedure CompressStreamBits(Src: TMemoryStream; bits: Integer);
Var z: TZCompressionStream;
    mem: TMemoryStream;
begin
  mem := TMemoryStream.Create;
  try
    z := TZCompressionStream.Create(mem, zcFastest, bits);
    try
      Src.Seek32(0, soBeginning);
      z.CopyFrom(Src, Src.Size);
    finally
      z.Free; // 先释放压缩流,确保所有数据写入mem
    end;
    
    mem.Seek32(0, soBeginning);
    Src.Clear;
    Src.SetSize(mem.Size);
    Src.Write(mem.Memory^, mem.Size);
  finally
    mem.Free;
  end;
end;

额外优化:使用try...finally结构确保资源无论是否出错都能正确释放,避免内存泄漏。

内容的提问来源于stack exchange,提问作者hikari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 20:25:14