Delphi XE 和 ZLib 问题

2023-11-24

我在 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 字符串。显然你反转箭头来减压。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Delphi XE 和 ZLib 问题 的相关文章

随机推荐

  • 为 iOS Metal 中 MTLBuffer 使用的数据分配内存

    作为后续问题这个答案 我正在尝试用 Metal 中的内核函数替换 CPU 上运行的 for 循环 以并行化计算并提高性能 我的函数基本上是一个卷积 由于我反复收到输入数组值的新数据 数据源于AVCaptureSession 似乎使用newB
  • Java Comparator 给出要比较的属性的名称

    我的问题是这样的 我必须订购一个数据表 表的每一行都是一个存储在 List 中的对象 我们称之为 TableObject 每列数据都是该类的一个属性 通常是字符串 当用户单击任何列时 我必须执行典型的数据排序 所以我考虑将 List 更改为
  • gdb如何显示线程名称

    我的应用程序中创建了许多线程 当我执行命令 infothreads 时 一些线程名称在 gdb 中可见 而其他线程名称则不显示 如何获取所有线程名称本身而不是像 0xb7fe1424 这样的十六进制值 4 Thread 0xb68ffb70
  • 在 Open XML SDK 中的单词书签后插入 OpenXmlElement

    我可以使用以下代码访问我的Word文档中的书签 var res from bm in mainPart Document Body Descendants
  • 如何复制 FTP 服务器上的文件?

    如何复制 FTP 服务器上的文件 我的目标是复制ftp www mysite com test jpg to ftp www mysite com testcopy jpg 要重命名文件 我会使用 var request FtpWebReq
  • 导航栏 rightbaritem 图像按钮错误 iOS 11

    这段代码在ios10上运行正常 我得到了我的标签和一个图像按钮 这是用户照片个人资料 圆形 好的 但是当运行 xcode 9 ios11 模拟器时 我发现它被拉伸了 按钮框架必须是 32x32 当检查 sim 并获取视图并告诉 xcode
  • 如何在日期选择器对话框中设置日期限制

    我想对日期进行限制 以便用户不能选择更多的日期 例如 如果今天是 1 月 1 日 那么用户不应选择超过 7 个日期 我的意思是他不能选择 1 月 9 日 我还希望他不要选择月份和年份 所以我限制他在一周内完成任务 到目前为止我所做的是显示日
  • 为什么 NodeJS KeepAlive 似乎没有按预期工作?

    引自TCP 保活操作方法 为了理解什么是 TCP keepalive 我们将称之为 keepalive 确实如此 您只需读取名称即可 keep TCP 活 这意味着您将能够检查已连接的套接字 也称为TCP套接字 并判断连接是否是 仍在运行或
  • 使用 Express 从 NodeJS 服务器下载文件

    如何将服务器中的文件下载到访问 NodeJS 服务器中页面的计算机 我正在使用 ExpressJS 并且我一直在尝试这个 app get download function req res var file fs readFileSync
  • 如何从 android 调用 ksoap web 服务?

    我有一个小困惑 在我们的移动应用程序中 有一个从 ios 调用的 ksoap Web 服务 如下所示 并正确获取数据 在下面的Web服务中 您可以从以下代码中看到 有一些参数需要传递给Web服务 void callwebservice NS
  • 在用户不点击通知的情况下处理数据负载?

    在后台时 应用程序会接收通知托盘中的通知负载 并且仅在用户点击通知时处理数据负载 有没有办法在用户不点击通知的情况下处理数据有效负载 基于 FCM 文档处理消息 App state Notification Data Both Foregr
  • document.getElementById 是否返回实时 dom 元素?

    Does document getElementByIdJavaScript 返回一个实时 DOM 元素 出于性能原因我有兴趣知道 标准和 实时 之间的区别通常用于lists的元素 document getElementById返回对 DO
  • 尝试读取数组上的属性“名称”(查看:C:\xampp\htdocs\Testing\resources\views\product.blade.php)

    我是 Laravel 的初学者 当我将统计表放入 Blade 中时 我收到此警告 尝试读取数组上的属性 名称 查看 C xampp htdocs Testing resources views product blade php 这是控制器
  • Android NFC 读取 ISO15693 RFID 标签

    我正在尝试使用 nfc android 库读取 ISO15693 RFID 标签 以下是有关标签的更多信息 http img42 com gw07d 标签 ID 已正确读取 但标签中的数据未正确读取 onCreate Method init
  • 如何在android中以编程方式应用低音效果

    我正在尝试应用低音效果通过使用以下代码以编程方式 BassBoost bassBoost new BassBoost 0 audioSessionId bassBoost setEnabled true BassBoost Settings
  • Google Android 会支持 .NET 吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 Locked 这个问题及其
  • 编译器会优化重复的数学计算吗?

    Java 编译器是否会优化简单的重复数学运算 例如 if prevX width curX width Do something with prevX width value else Do something with curX widt
  • 有没有办法更改Unity中的gradle.properties文件

    Unity 有一个默认的 gradle properties 文件 该文件在构建过程中添加 虽然可以如上所述更改 build gradle 和 settings gradle 文件 这里https docs unity3d com Manu
  • Java 线程 - 内存一致性错误

    我正在读一本Sun 的并发教程 但我无法理解到底是什么内存一致性错误是 我用谷歌搜索了一下 但没有找到任何有用的教程或文章 我知道这个问题是一个主观问题 因此您可以向我提供有关上述主题的文章的链接 如果您用一个简单的例子来解释它 那就太好了
  • Delphi XE 和 ZLib 问题

    我在 Delphi XE 中 ZLib 例程遇到一些问题 我正在尝试压缩一些字符串 并对它进行编码以通过 SOAP Web 服务发送 并不重要 ZDecompressString 的字符串结果与 ZcompressString 中使用的字符