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
相关产品推荐
相关产品推荐

