加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Delphi XE和ZLib问题

发布时间:2020-12-15 09:26:06 所属栏目:大数据 来源:网络整理
导读:我在Delphi XE中,我遇到了ZLib例程的一些问题…… 我正在尝试压缩一些字符串(并对其进行编码以通过SOAP Web服务发送 – 非常重要 – ) 来自ZDecompressString的字符串结果与ZCompressString中使用的不同. 例1: uses ZLib;// compressing string// ZCompress
我在Delphi XE中,我遇到了ZLib例程的一些问题……

我正在尝试压缩一些字符串(并对其进行编码以通过SOAP Web服务发送 – 非常重要 – )

来自ZDecompressString的字符串结果与ZCompressString中使用的不同.

例1:

uses ZLib;
// compressing string
// ZCompressString('1234567890',zcMax); 
// compressed string ='xú3426153·°4'

// Uncompressing the result of ZCompressString,don't return the same:
// ZDecompressString('xú3426153·°4'); 
// uncompressed string = '123456789'

if '1234567890' <> ZDecompressString(ZCompressString('1234567890',zcMax)) then
  ShowMessage('Compression/Decompression fails');

例2:

Uses ZLib;
// compressing string
// ZCompressString('12345678901234567890',zcMax) 
// compressed string ='xú3426153·°40?3'

// Uncompressing the result of ZCompressString,don't return the same:
// ZDecompressString('xú3426153·°40?3') 
// uncompressed string = '12345678901'

if '12345678901234567890' <> ZDecompressString(ZCompressString('12345678901234567890',zcMax)) then
  ShowMessage('Compression/Decompression fails');

使用的函数来自其他一些关于压缩和解压缩的帖子

function TForm1.ZCompressString(aText: string; aCompressionLevel: TZCompressionLevel): string;
var
  strInput,strOutput: TStringStream;
  Zipper: TZCompressionStream;
begin
  Result:= '';
  strInput:= TStringStream.Create(aText);
  strOutput:= TStringStream.Create;
  try
    Zipper:= TZCompressionStream.Create(strOutput,aCompressionLevel);
    try
      Zipper.CopyFrom(strInput,strInput.Size);
    finally
      Zipper.Free;
    end;
    Result:= strOutput.DataString;
  finally
    strInput.Free;
    strOutput.Free;
  end;
end;

function TForm1.ZDecompressString(aText: string): string;
var
  strInput,strOutput: TStringStream;
  Unzipper: TZDecompressionStream;
begin
  Result:= '';
  strInput:= TStringStream.Create(aText);
  strOutput:= TStringStream.Create;
  try
    Unzipper:= TZDecompressionStream.Create(strInput);
    try
      strOutput.CopyFrom(Unzipper,Unzipper.Size);
    finally
      Unzipper.Free;
    end;
    Result:= strOutput.DataString;
  finally
    strInput.Free;
    strOutput.Free;
  end;
end;

哪里错了?

有人有同样的问题吗?

解决方法

与我所知的所有压缩码一样,ZLib是一种二进制压缩算法.它对字符串编码一无所知.您需要为其提供压缩的字节流.当你解压缩时,你会得到回字节流.

但是你正在使用字符串,因此需要在编码文本和字节流之间进行转换. TStringStream类正在您的代码中执行该操作.在创建字符串流实例时,可以为其提供文本编码.

只有您的代码不提供编码.因此使用默认的本地ANSI编码.这是第一个问题.这不是完整的Unicode编码.只要您使用本地ANSI代码页之外的字符,链就会崩溃.

通过在创建字符串流实例时提供编码来解决该问题.将编码传递给TStringStream构造函数.一个合理的选择是TEncoding.UTF8.在压缩器中创建strInput时,传递此值,在解压缩器中创建strOutput.

现在,您面临的下一个更大的问题是,您的压缩数据在任何编码中都可能不是有意义的字符串.如果切换到使用AnsiString而不是字符串,则可能使现有代码有效.但这是一个相当脆弱的解决方案.

从根本上说,你犯了将二进制数据视为文本的错误.压缩后,您就拥有了二进制数据.我的建议是您不要尝试将压缩二进制文件解释为文本.把它留作二进制.压缩到TBytesStream.并从TBytesStream解压缩.因此压缩器函数返回TBytes,解压缩器接收相同的TBytes.

如果由于某种原因必须压缩为字符串,则必须对压缩的二进制文件进行编码.使用base64做到这一点. EncdDecd单元可以为您完成.

压缩器的这个流程如下所示:string – > UTF-8字节 – >压缩字节 – > base64字符串.显然你反转箭头来解压缩.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读