Delphi 7 并解码 UTF-8 base64
Delphi 7 and decode UTF-8 base64
在 Delphi 7 中,我有一个用 Base64 编码的宽字符串(我从 Web 服务收到的 WideString 结果):
PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3RyaW5nPtiq2LPYqjwvc3RyaW5nPg==
当我解码它时,结果不是 UTF-8:
<?xml version="1.0"?>
<string>طھط³طھ</string>
但是当我用base64decode.org解码时,结果是真的:
<?xml version="1.0"?>
<string>تست</string>
我已经将 EncdDecd 单元用于 DecodeString 函数。
您遇到的问题是您正在使用 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 解析器处理这方面的问题。
作为 David Heffernan 精彩回答的附录,以及 Remy Lebeau 关于它如何在 Delphi 7 上被破坏的注释,我想添加一个功能,以帮助任何陷入 Delphi 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.
在 Delphi 7 中,我有一个用 Base64 编码的宽字符串(我从 Web 服务收到的 WideString 结果):
PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3RyaW5nPtiq2LPYqjwvc3RyaW5nPg==
当我解码它时,结果不是 UTF-8:
<?xml version="1.0"?>
<string>طھط³طھ</string>
但是当我用base64decode.org解码时,结果是真的:
<?xml version="1.0"?>
<string>تست</string>
我已经将 EncdDecd 单元用于 DecodeString 函数。
您遇到的问题是您正在使用 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 解析器处理这方面的问题。
作为 David Heffernan 精彩回答的附录,以及 Remy Lebeau 关于它如何在 Delphi 7 上被破坏的注释,我想添加一个功能,以帮助任何陷入 Delphi 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.