gpt4 book ai didi

Delphi XE 和 ZLib 问题

转载 作者:行者123 更新时间:2023-12-03 15:23:29 24 4
gpt4 key购买 nike

我在 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„³'

// Uncompressing the result of ZCompressString, don't return the same:
// ZDecompressString('xÚ3426153·°40„³')
// 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 而不是 string,您可能会使现有代码正常工作。但这是一个相当脆弱的解决方案。

从根本上来说,您犯了将二进制数据视为文本的错误。压缩后,您将获得二进制数据。我的建议是您不要尝试将压缩的二进制文件解释为文本。将其保留为二进制。压缩为 TBytesStream。并从 TBytesStream 解压缩。因此压缩器函数返回 TBytes 并且解压缩器接收相同的 TBytes

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

压缩器的流程如下所示:字符串 -> UTF-8 字节 -> 压缩字节 -> base64 字符串。显然你反转箭头来减压。

关于Delphi XE 和 ZLib 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21910841/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com