将AnsiString转换为Unicode字符串

时间:2010-04-01 00:12:32

标签: delphi unicode encoding delphi-2010

我正在将D2006程序转换为D2010。我的数据库中每个字符串都有一个存储在单个字节中的值,我需要将其加载到具有LoadFromStream的控件中,因此我的计划是将字符串写入流并将其与LoadFromStream一起使用。但它没有用。在研究这个问题时,我看到一个问题告诉我,我真的不明白从AnsiString到Unicode字符串的转换是如何工作的。这是一段独立的代码,说明了我感到困惑的问题:;

procedure TForm1.Button1Click(Sender: TObject); {$O-}
var
  sBuffer: String;
  oStringStream: TStringStream;
  sAnsiString: AnsiString;
  sUnicodeString: String;
  iSize1,
  iSize2: Word;
begin
  sAnsiString := '12345';
  oStringStream := TStringStream.Create(sBuffer);
  sUnicodeString := sAnsiString;
  iSize1 := StringElementSize(sAnsiString);
  iSize2 := StringElementSize(sUnicodeString);
  oStringStream.WriteString(sUnicodeString);
end;

如果你在最后一行中断,并检查oStringStream的Bytes属性,你会发现它看起来像这样:

Bytes (49 {$31}, 50 {$32}, 51 {$33}, 52 {$34}, 53 {$35}

我原以为它可能看起来像

(49 {$31}, 00 {$00}, 50 {$32}, 00 {$00}, 51 {$33}, 00 {$00}, 
 52 {$34}, 00 {$00}, 53 {$35}, 00 {$00} ...

显然我的期望是错误的。但是,如何将AnsiString转换为unicode?

我没有从LoadFromStream中获得正确的结果,因为它一次从流中读取两个字节,但它接收的数据不是那样排列的。我应该做些什么来为LoadFromStream提供基于unicode字符串的良好数据流?

感谢您的帮助。

4 个答案:

答案 0 :(得分:5)

oStringStream.WriteString的参数是什么类型的?如果它是AnsiString,你有一个从Unicode到Ansi的隐式转换,这解释了你的例子。


更新:现在真正的问题是TStringStream如何在内部存储数据。 在以下代码示例(Delphi 2009)

procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
  SS: TStringStream;

begin
  S:= 'asdfg';
  SS:= TStringStream.Create(S);  // 1 byte per char
  SS.WriteString('321');
  Label1.Caption:= SS.DataString;
  SS.Free;
end;

TStringStream在内部使用默认的系统ANSI编码(每个字符1个字节)。 构造函数和WriteString过程将字符串参数从unicode转换为ANSI。

要覆盖此行为,您必须在构造函数中明确声明编码:

procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
  SS: TStringStream;

begin
  S:= 'asdfg';
  SS:= TStringStream.Create(S, TEncoding.Unicode);  // 2 bytes per char
  SS.WriteString('321');
  Label1.Caption:= SS.DataString;
  SS.Free;
end;

答案 1 :(得分:1)

在Delphi的最新版本中,您可以使用TEncoding:

TEncoding.UTF8.GetString(TEncoding.ANSI.GetBytes(MyString))

答案 2 :(得分:0)

我想你想用:

LoadFromStream(stream, TEncoding.ASCII);

如果您的单字节文本不是ASCII而是基于代码页,那么这可能有效:

LoadFromStream(stream, TEncoding.GetEncoding(1252));

其中“1252”是单字节文本所基于的代码页。

答案 3 :(得分:0)

流格式很大程度上取决于TStringStream.Encoding。在您的示例中,使用的代码页应与sBuffer相同(请参阅TStringStream.Create中的实现)。

由于oStringStream.WriteString(sUnicodeStream);似乎保存为单个字节,我假设sBuffer是Ansistring或RawByteString。

现在......为什么阅读失败...你还没有给我们提供你如何回读该流的例子。