Delphi XE和ZLib问题
我在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字符串.显然你反转箭头来解压缩. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |