对于unicode Delphi,TStream到TStringList失败

时间:2014-08-12 21:08:49

标签: delphi unicode stream delphi-7 delphi-xe

如下面代码的Test2所示,TStringList被转换为TStream,然后TStream被转换回TStringList。但是,在Delphi 7 Test2中,Test1Test2相同。在unicode Delphi中,program Project1; {$APPTYPE CONSOLE} {$R *.res} uses Classes, SysUtils; // http://stackoverflow.com/questions/732666 // Converting TMemoryStream to String in Delphi 2009 function MemoryStreamToString(M: TMemoryStream): string; begin SetString(Result, PChar(M.Memory), M.Size div SizeOf(Char)); end; procedure Test1; var SrcList: TStrings; S: String; AStream: TStream; begin SrcList := TStringList.Create; try with SrcList do begin Add('aa'); Add('bb'); Add('cc'); end; S := SrcList.Text; AStream := TMemoryStream.Create; try // AStream.Write(S[1], Length(S)); // AStream.Write(S[1], Length(S) * SizeOf(Char)); AStream.Write(Pointer(S)^, Length(S) * SizeOf(Char)); WriteLn(MemoryStreamToString(TMemoryStream(AStream))); finally AStream.Free; end; finally SrcList.Free; end; end; procedure Test2; var SrcList: TStrings; S: String; AStream: TStream; DestList: TStringList; I: Integer; begin SrcList := TStringList.Create; try with SrcList do begin Add('aa'); Add('bb'); Add('cc'); end; S := SrcList.Text; AStream := TMemoryStream.Create; try // AStream.Write(S[1], Length(S)); // AStream.Write(S[1], Length(S) * SizeOf(Char)); AStream.Write(Pointer(S)^, Length(S) * SizeOf(Char)); DestList := TStringList.Create; try AStream.Position := 0; DestList.LoadFromStream(AStream); WriteLn(DestList.Text); finally DestList.Free; end; finally AStream.Free; end; finally SrcList.Free; end; end; begin try Test1; Test2; except on E: Exception do WriteLn(E.ClassName, ': ', E.Message); end; Readln; end. 没有给出正确的结果。你能帮忙建议出现什么问题吗?

{{1}}

1 个答案:

答案 0 :(得分:10)

Test1将原始String数据按原样写入TMemoryStream,然后按原样将其读回String,因此所有版本中的所有内容都正确匹配德尔福由于类似的原因,Test2在Delphi 2007及更早版本中有效。

Delp 2009及更高版本中的

Test2失败,因为您没有考虑TStrings.LoadFrom...()(和TStrings.SaveTo...()TEncoding - 在这些版本的Delphi中。您正在编写UTF-16编码数据到TMemoryStream而没有前面的BOM,然后您没有告诉LoadFromStream()该流是UTF-16编码的。它试图找到一个BOM,当它找不到时,它会使用TEncoding.Default(又名8bit Ansi)加载流(为了向后兼容遗留代码)。

因此,在此示例中,您需要在Delphi 2009及更高版本中加载流数据时指定正确的数据编码:

DestList.LoadFromStream(AStream, TEncoding.Unicode);