如何将WideString(或其他长字符串)转换为UTF-8字节数组?
像这样的函数将会满足您的需求:
function UTF8Bytes(const s: UTF8String): TBytes;
begin
Assert(StringElementSize(s)=1);
SetLength(Result, Length(s));
if Length(Result)>0 then
Move(s[1], Result[0], Length(s));
end;
你可以使用任何类型的字符串调用它,RTL 将从传递的字符串编码转换为 UTF-8。因此,请不要被欺骗认为您必须在调用之前转换为 UTF-8,只需传入任何字符串,让 RTL 来处理就行了。function UTF8Bytes(const s: UTF8String): TBytes;
begin
Assert(StringElementSize(s)=1);
SetLength(Result, Length(s)+1);
if Length(Result)>0 then
Move(s[1], Result[0], Length(s));
Result[high(Result)] := 0;
end;
TEncoding.UTF8.GetBytes
。GetBytes
将非常浪费。编译器将把输入字符串转换为UnicodeString,因为这是GetBytes
允许的唯一字符串参数,而GetBytes
将把字符再次转换为UTF-8以生成其结果。 - Rob Kennedyvar
ws: WideString;
u8s: UTF8String;
u8s := ws;
CP_UTF8
。在Delphi 7及更高版本中,您可以使用提供的库函数Utf8Encode
。对于更早的版本,您可以从其他库(例如JCL)中获取该函数。您还可以使用Windows API编写自己的转换函数:function CustomUtf8Encode(const ws: WideString): UTF8String;
var
n: Integer;
begin
n := WideCharToMultiByte(cp_UTF8, 0, PWideChar(ws), Length(ws), nil, 0, nil, nil);
Win32Check(n <> 0);
SetLength(Result, n);
n := WideCharToMultiByte(cp_UTF8, 0, PWideChar(ws), Length(ws), PAnsiChar(Result), n, nil, nil);
Win32Check(n = Length(Result));
end;
var S: UTF8String;
B: TBytes;
begin
S := 'Șase sași în șase saci';
SetLength(B, Length(S)); // Length(s) = 26 for this 22 char string.
CopyMemory(@B[0], @S[1], Length(S));
end.
根据您需要字节的用途,您可能想要包含一个NULL终止符。
对于生产代码,请确保测试空字符串。添加所需的3-4行代码将使示例更难阅读。
Length
函数的工作原理! - Andreas RejbrandWideString -> UTF8:
http://www.freepascal.org/docs-html/rtl/system/utf8decode.html
相反:
http://www.freepascal.org/docs-html/rtl/system/utf8encode.html
请注意,在 D2009 之前的系统(包括当前的 Free Pascal)中将 widestring 分配给 ansistring 将转换为本地 ANSI 编码,导致字符混乱。
Delphi
而不是free-pascal
,@David的答案适用于Delphi而不适用于Free Pascal。但是上面的代码可能也适用于Free Pascal。我不知道。你可以试一下。 - Andreas Rejbrand