In Delphi 7, I have a widestring encoded with Base64(That I received from a Web service with WideString result) :
在Delphi 7中,我有一个用Base64编码的widestring(我从一个带有widestring结果的Web服务中收到):
PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3RyaW5nPtiq2LPYqjwvc3RyaW5nPg==
PD94bWwgdmVyc2lvbj0iMS4wIj8 + DQo8c3RyaW5nPtiq2LPYqjwvc3RyaW5nPg = =
when I decoded it, that result is not UTF-8:
当我解码时,结果不是UTF-8:
<?xml version="1.0"?>
<string>طھط³طھ</string>
But when I decoded it by base64decode.org, result is true :
但当我通过base64decode.org对它进行解码时,结果是正确的:
<?xml version="1.0"?>
<string>تست</string>
I have use EncdDecd unit for DecodeString function.
我使用了EncdDecd单元来进行解码。
2 个解决方案
#1
4
The problem you have is that you are using DecodeString
. That function, in Delphi 7, treats the decoded binary data as being ANSI encoded. And the problem is that your text is UTF-8 encoded.
您的问题是您使用的是DecodeString。在Delphi 7中,该函数将解码的二进制数据视为ANSI编码。问题是你的文本是UTF-8编码的。
To continue with the EncdDecd
unit you have a couple of options. You can switch to DecodeStream
. For instance, this code will produce a UTF-8 encoded text file with your data:
要继续使用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.
Or you could continue with DecodeString
, but then immediately decode the UTF-8 text to a WideString
. Like this:
或者您可以继续使用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.
If the content of the file can be represented in your application's prevailing ANSI locale then you can convert that WideString
to a plain AnsiString
.
如果该文件的内容可以在应用程序当前的ANSI语言环境中表示,那么您可以将该WideString转换为普通的AnsiString。
var
wstr: WideString;
str: string; // alias to AnsiString
....
wstr := ... // as before
str := wstr;
However, I really don't think that using ANSI encoded text is going to lead to a very fruitful programming life. I encourage you to embrace Unicode solutions.
然而,我真的不认为使用ANSI编码的文本将会导致一个非常丰富的编程生活。我鼓励您使用Unicode解决方案。
Judging by the content of the decoded data, it is XML. Which is usually handed to an XML parser. Most XML parsers will accept UTF-8 encoded data, so you quite probably can base64 decode to a memory stream using DecodeStream
and then hand that stream off to your XML parser. That way you don't need to decode the UTF-8 to text and can let the XML parser deal with that aspect.
从解码数据的内容判断,它是XML。通常将其传递给XML解析器。大多数XML解析器将接受UTF-8编码的数据,因此您很可能可以使用DecodeStream将base64解码到一个内存流,然后将该流传递给XML解析器。这样,您就不需要将UTF-8解码为文本,并且可以让XML解析器处理这个方面。
#2
1
As an addendum to David Heffernan's awesome answer, and Remy Lebeau's note on how it's broken on Delphi 7, I would like to add a function that will help any developer stuck on Delphi 7.
作为David Heffernan令人惊叹的回答的补充,以及Remy Lebeau关于Delphi 7上的坏消息的说明,我想添加一个功能,可以帮助任何开发人员在Delphi 7上被卡。
Since UTF8Decode()
is broken in Delphi 7, I found a function in a forum that solved my problem:
因为在Delphi 7中,UTF8Decode()被破坏,所以我在一个解决我的问题的论坛中找到了一个函数:
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;
So now, you can use DecodeString
, and then decode the UTF-8 text to a WideString
using this function:
现在,您可以使用DecodeString,然后使用这个函数将UTF-8文本解码为WideString:
begin
Utf8 := DecodeString(Data);
wstr := UTF8ToWideString(Utf8);
end.
#1
4
The problem you have is that you are using DecodeString
. That function, in Delphi 7, treats the decoded binary data as being ANSI encoded. And the problem is that your text is UTF-8 encoded.
您的问题是您使用的是DecodeString。在Delphi 7中,该函数将解码的二进制数据视为ANSI编码。问题是你的文本是UTF-8编码的。
To continue with the EncdDecd
unit you have a couple of options. You can switch to DecodeStream
. For instance, this code will produce a UTF-8 encoded text file with your data:
要继续使用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.
Or you could continue with DecodeString
, but then immediately decode the UTF-8 text to a WideString
. Like this:
或者您可以继续使用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.
If the content of the file can be represented in your application's prevailing ANSI locale then you can convert that WideString
to a plain AnsiString
.
如果该文件的内容可以在应用程序当前的ANSI语言环境中表示,那么您可以将该WideString转换为普通的AnsiString。
var
wstr: WideString;
str: string; // alias to AnsiString
....
wstr := ... // as before
str := wstr;
However, I really don't think that using ANSI encoded text is going to lead to a very fruitful programming life. I encourage you to embrace Unicode solutions.
然而,我真的不认为使用ANSI编码的文本将会导致一个非常丰富的编程生活。我鼓励您使用Unicode解决方案。
Judging by the content of the decoded data, it is XML. Which is usually handed to an XML parser. Most XML parsers will accept UTF-8 encoded data, so you quite probably can base64 decode to a memory stream using DecodeStream
and then hand that stream off to your XML parser. That way you don't need to decode the UTF-8 to text and can let the XML parser deal with that aspect.
从解码数据的内容判断,它是XML。通常将其传递给XML解析器。大多数XML解析器将接受UTF-8编码的数据,因此您很可能可以使用DecodeStream将base64解码到一个内存流,然后将该流传递给XML解析器。这样,您就不需要将UTF-8解码为文本,并且可以让XML解析器处理这个方面。
#2
1
As an addendum to David Heffernan's awesome answer, and Remy Lebeau's note on how it's broken on Delphi 7, I would like to add a function that will help any developer stuck on Delphi 7.
作为David Heffernan令人惊叹的回答的补充,以及Remy Lebeau关于Delphi 7上的坏消息的说明,我想添加一个功能,可以帮助任何开发人员在Delphi 7上被卡。
Since UTF8Decode()
is broken in Delphi 7, I found a function in a forum that solved my problem:
因为在Delphi 7中,UTF8Decode()被破坏,所以我在一个解决我的问题的论坛中找到了一个函数:
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;
So now, you can use DecodeString
, and then decode the UTF-8 text to a WideString
using this function:
现在,您可以使用DecodeString,然后使用这个函数将UTF-8文本解码为WideString:
begin
Utf8 := DecodeString(Data);
wstr := UTF8ToWideString(Utf8);
end.