在Delphi 7中,我有一个使用Base64编码的宽字符串(我从具有WideString结果的Web服务收到):
PD94bWwgdmVyc2lvbj0iMS4wIj8 + DQo8c3RyaW5nPtiq2LPYqjwvc3RyaW5nPg ==
当我解码它时,结果不是UTF-8:
<?xml version="1.0"?>
<string>طھط³طھ</string>
但是当我用base64decode.org解码它时,结果为真:
<?xml version="1.0"?>
<string>تست</string>
我使用EncdDecd单元作为DecodeString函数。
答案 0 :(得分:5)
您遇到的问题是您使用的是DecodeString
。在Delphi 7中,该函数将解码的二进制数据视为ANSI编码。问题是您的文本是UTF-8编码的。
要继续使用EncdDecd
单元,您有几个选择。您可以切换到DecodeStream
。例如,此代码将生成包含您的数据的UTF-8编码文本文件:
{$APPTYPE CONSOLE}
uses
Classes,
EncdDecd;
const
Data = 'PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3RyaW5nPtiq2LPYqjwvc3RyaW5nPg==';
var
Input: TStringStream;
Output: TFileStream;
begin
Input := TStringStream.Create(Data);
try
Output := TFileStream.Create('C:\desktop\out.txt', fmCreate);
try
DecodeStream(Input, Output);
finally
Output.Free;
end;
finally
Input.Free;
end;
end.
或者您可以继续DecodeString
,但随后立即将UTF-8文本解码为WideString
。像这样:
{$APPTYPE CONSOLE}
uses
Classes,
EncdDecd;
const
Data = 'PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3RyaW5nPtiq2LPYqjwvc3RyaW5nPg==';
var
Utf8: AnsiString;
wstr: WideString;
begin
Utf8 := DecodeString(Data);
wstr := UTF8Decode(Utf8);
end.
如果文件的内容可以在您的应用程序的主流ANSI区域设置中表示,那么您可以将WideString
转换为普通AnsiString
。
var
wstr: WideString;
str: string; // alias to AnsiString
....
wstr := ... // as before
str := wstr;
但是,我真的不认为使用ANSI编码的文本会带来非常富有成效的编程生活。我鼓励你接受Unicode解决方案。
根据解码数据的内容判断,它是XML。通常将其传递给XML解析器。大多数XML解析器都接受UTF-8编码数据,因此您很可能使用DecodeStream
将base64解码为内存流,然后将该流传递给XML解析器。这样您就不需要将UTF-8解码为文本,并且可以让XML解析器处理该方面。
答案 1 :(得分:1)
作为David Heffernan的精彩答案的附录,以及Remy Lebeau关于它如何在Delphi 7上被打破的说明,我想添加一个功能,可以帮助任何开发人员坚持德尔福7。
由于UTF8Decode()
在Delphi 7中被破坏,我在forum中发现了一个解决了我的问题的函数:
function UTF8ToWideString(const S: AnsiString): WideString;
var
BufSize: Integer;
begin
Result := '';
if Length(S) = 0 then Exit;
BufSize := MultiByteToWideChar(CP_UTF8, 0, PAnsiChar(S), Length(S), nil, 0);
SetLength(result, BufSize);
MultiByteToWideChar(CP_UTF8, 0, PANsiChar(S), Length(S), PWideChar(Result), BufSize);
end;
现在,您可以使用DecodeString
,然后使用此函数将UTF-8文本解码为WideString
:
begin
Utf8 := DecodeString(Data);
wstr := UTF8ToWideString(Utf8);
end.