gpt4 book ai didi

delphi - 如何在 Delphi 7 中将字符串存储在流中并在 XE6 中恢复移动应用程序?

转载 作者:行者123 更新时间:2023-12-03 09:56:52 25 4
gpt4 key购买 nike

我开发了一个通过 HTTP 进行通信的服务器和一个移动客户端。服务器是用 Delphi 7 编写的(因为它必须与旧代码兼容),客户端是用 XE6 编写的移动应用程序。服务器向客户端发送包含字符串的数据流。一个问题与编码有关。

在服务器上,我尝试以 UTF8 传递字符串:

//Writes string to stream
procedure TStreamWrap.WriteString(Value: string);
var
BytesCount: Longint;
UTF8: string;
begin
UTF8 := AnsiToUtf8(Value);
BytesCount := Length(UTF8);

WriteLongint(BytesCount); //It writes Longint to FStream: TStream

if BytesCount > 0 then
FStream.WriteBuffer(UTF8[1], BytesCount);
end;

因为它是用 Delphi7 编写的,所以 Value 是一个单字节字符串。

在客户端上,我以 UTF8 读取字符串并将其编码为 Unicode
//Reads string from current position of stream
function TStreamWrap.ReadString: string;
var
BytesCount: Longint;
UTF8: String;
begin
BytesCount := ReadLongint;
if BytesCount = 0 then
Result := ''
else
begin
SetLength(UTF8, BytesCount);

FStream.Read(Pointer(UTF8)^, BytesCount);

Result := UTF8ToUnicodeString(UTF8);
end;
end;

但它不起作用,当我用 ShowMessage 显示字符串时字母是错误的。那么如何在Delphi 7中存储字符串并在移动应用程序上的XE6中恢复呢?我应该在表示字符串的数据的开头添加 BOM 吗?

最佳答案

要在移动应用程序中读取 UTF8 编码的字符串,您可以使用字节数组和 TEncoding类(class)。像这样:

function TStreamWrap.ReadString: string;
var
ByteCount: Longint;
Bytes: TBytes;
begin
ByteCount := ReadLongint;
if ByteCount = 0 then
begin
Result := '';
exit;
end;

SetLength(Bytes, ByteCount);
FStream.Read(Pointer(Bytes)^, ByteCount);
Result := TEncoding.UTF8.GetString(Bytes);
end;

这段代码可以满足您在 XE6 中的需要,但当然,这段代码在 Delphi 7 中无法编译,因为它使用了 TEncoding .更重要的是,您的 TStreamWrap.WriteString实现在 Delphi 7 中完成了你想要的,但在 XE6 中被破坏了。

现在看起来您对 Delphi 7 和 Delphi XE6 版本使用相同的代码库。这意味着您可能需要使用一些条件编译来处理这些版本之间不同的文本。

就我个人而言,我会按照 TEncoding 的示例来做到这一点。 .你需要的是一个转换原生Delphi的函数 string到 UTF-8 编码的字节数组,以及相反方向的相应函数。

所以,让我们考虑字符串到字节函数。我不记得 Delphi 7 是否有 TBytes类型。我怀疑不是。所以让我们定义它:
{$IFNDEF UNICODE} // definitely use a better conditional than this in real code
type
TBytes = array of Byte;
{$ENDIF}

然后我们可以定义我们的函数:
function StringToUTF8Bytes(const s: string): TBytes;
{$IFDEF UNICODE}
begin
Result := TEncoding.UTF8.GetBytes(s);
end;
{$ELSE}
var
UTF8: UTF8String;
begin
UTF8 := AnsiToUtf8(s);
SetLength(Result, Length(UTF8));
Move(Pointer(UTF8)^, Pointer(Result)^, Length(Result));
end;
{$ENDIF}

相反方向的功能对您来说应该是微不足道的。

一旦封装了两个 Delphi 版本之间的文本编码处理差异,您就可以在程序的其余部分编写条件自由代码。例如,您将编码 WriteString像这样:
procedure TStreamWrap.WriteString(const Value: string);
var
UTF8: TBytes;
ByteCount: Longint;
begin
UTF8 := StringToUTF8Bytes(Value);
ByteCount := Length(UTF8);
WriteLongint(ByteCount);
if ByteCount > 0 then
FStream.WriteBuffer(Pointer(UTF8)^, ByteCount);
end;

关于delphi - 如何在 Delphi 7 中将字符串存储在流中并在 XE6 中恢复移动应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23606139/

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