如下面代码的Test2
所示,TStringList被转换为TStream,然后TStream被转换回TStringList。但是,在Delphi 7 Test2
中,Test1
与Test2
相同。在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}}
答案 0 :(得分:10)
Test1
将原始String
数据按原样写入TMemoryStream
,然后按原样将其读回String
,因此所有版本中的所有内容都正确匹配德尔福由于类似的原因,Test2
在Delphi 2007及更早版本中有效。
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);