sn_*_*a_v 1 xml delphi indy tstream delphi-11-alexandria
我已经从 Delphi 6 迁移到 Delphi 11(64 位版本),并且我正在使用 Indy 和 ZLib 组件。我已经从 Indy 9 迁移到 Indy 10,使用组件发布 API,在此之前我通过以下方式将字符串写入流:
var
XML: String;
stream: TStream;
begin
...
stream.WriteBuffer(XML[1], Length(XML) * 2);
Run Code Online (Sandbox Code Playgroud)
然后使用 ZLib 组件对其进行压缩。但当它到达服务器时,它会包含消息中每个字母的空格:
Run Code Online (Sandbox Code Playgroud)< h t m l > u s e r < / h t m l >
关于如何解决这个问题有什么想法吗?
自 Delphi 2009 以来,该string类型一直是 UTF-16 编码的UnicodeString。您正在将 a 的原始字符字节string 按原样写入您的TStream,因此您需要将字符串的长度乘以 2,因为SizeOf(Char)是 2 个字节。您看到的空格实际上是 byte ,因为 UTF-16 中的 ASCII 字符的#$00高字节设置为零。
但在 Delphi 6 中,string类型改为 8 位AnsiString,并且SizeOf(Char)为 1 个字节。
为了在 Delphi 11 中获得与 Delphi 6 中相同的行为,您需要先将字符转换UnicodeString为编码字节,然后再将它们写入TStream. XML 的默认/首选编码是 UTF-8(但可以是您选择在 XML 的序言中指定的任何其他字符集),例如:
var
XML: string;
utf8: UTF8String;
stream: TStream;
...
utf8 := UTF8String(XML); // use UTF8Encode() in Delphi 6
stream.WriteBuffer(utf8[1], Length(utf8));
Run Code Online (Sandbox Code Playgroud)
或者,Indy 在单元中具有重载WriteStringToStream()函数IdGlobal,这些函数具有可选ADestEncoding参数,例如:
uses
..., IdGlobal;
var
XML: string;
stream: TStream;
...
WriteStringToStream(stream, XML, IndyTextEncoding_UTF8);
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用 Delphi 自己的类,该类在 Delphi 2009+ 中TStringStream具有可选参数,例如:TEncoding
var
XML: string;
stream: TStream;
...
stream := TStringStream.Create(XML, TEncoding.UTF8);
Run Code Online (Sandbox Code Playgroud)
或者,根本不使用 a TStream。Indy 的TIdIOHandler类有一个DefStringEncoding用于文本读/写的属性,它的Write(string)和WriteLn(string)方法也有一个可选AByteEncoding参数,例如:
var
XML: string;
...
Connection.IOHandler.DefStringEncoding := IndyTextEncoding_UTF8;
...
Connection.IOHandler.Write(XML);
Run Code Online (Sandbox Code Playgroud)
或者:
var
XML: string;
...
Connection.IOHandler.Write(XML, IndyTextEncoding_UTF8);
Run Code Online (Sandbox Code Playgroud)