我正在将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字符串的良好数据流?
感谢您的帮助。
答案 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。
现在......为什么阅读失败...你还没有给我们提供你如何回读该流的例子。