gpt4 book ai didi

delphi - 对于 unicode Delphi,TStream 到 TStringList 失败

转载 作者:行者123 更新时间:2023-12-02 03:47:21 28 4
gpt4 key购买 nike

如下面代码的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 及更早版本中工作。

Test2 在 Delphi 2009 及更高版本中失败,因为您没有考虑 TStrings.LoadFrom...() (和 TStrings.SaveTo.. .()) 在这些版本的 Delphi 中是支持 TEncoding 的。您将 UTF-16 编码的数据写入前面没有 BOM 的 TMemoryStream 中,然后您没有告诉 LoadFromStream() 该流是 UTF-16 编码的。它尝试查找 BOM,当找不到 BOM 时,它会使用 TEncoding.Default(又名 8 位 Ansi)加载流(为了向后兼容旧代码)。

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

DestList.LoadFromStream(AStream, TEncoding.Unicode);

关于delphi - 对于 unicode Delphi,TStream 到 TStringList 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25274070/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com