[英]Ansi TStringList in Delphi XE for non-Unicode compatibility
[英]TStream to TStringList fails for unicode Delphi
如下面代碼的Test2
所示,TStringList被轉換為TStream,然后TStream被轉換回TStringList。 但是,在Delphi 7中, Test2
給出了與Test1
相同的功能。 在unicode Delphi中, Test2
沒有給出正確的結果。 你能幫忙建議出現什么問題嗎?
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.
Test1
將原始String
數據按原樣寫入TMemoryStream
,然后將其原樣讀回String
,因此所有版本的Delphi中都能正確匹配。 由於類似的原因, Test2
在Delphi 2007及更早版本中運行。
在Delphi 2009及更高版本中, Test2
失敗了,因為您沒有考慮到TStrings.LoadFrom...()
(以及TStrings.SaveTo...()
)在這些版本的Delphi中是TEncoding
-aware。 你正在編寫UTF-16編碼數據到TMemoryStream
在前面沒有BOM,然后你不告訴LoadFromStream()
該流為UTF-16編碼。 它試圖找到一個BOM,當它找不到時,它會使用TEncoding.Default
(又名8bit Ansi)加載流(為了向后兼容遺留代碼)。
因此,在此示例中,您需要在Delphi 2009及更高版本中加載流數據時指定正確的流數據編碼:
DestList.LoadFromStream(AStream, TEncoding.Unicode);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.