使用MyStringList.LoadFromStream(Str)而不是MyStringList.Text := PChar( Str.Memory).
首先,您的TStream数据不是以空值结尾的,但是使用PChar您的方式需要一个空值终止符(您可以使用SetString()字符串变量来解决这个问题)。
其次,从 D2009 开始,String现在是UnicodeString代替,AnsiString现在PChar是PWideChar代替PAnsiChar. 您的TStream数据是 Ansi 而不是 Unicode(即使在 D2009+ 中,因为SaveToStream()默认使用TEncoding.DefaultAnsi 来编码流数据),因此将数据转换为PWideChar将垃圾分配给您的TStringList.
在所有版本中,您都应该使用LoadFromStream(),但如果您想坚持设置Text属性,那么您需要这样做,这适用于所有版本:
var
...
S: AnsiString;
begin
...
MyBackupStream.ReadBuffer(StrSz, SizeOf(Integer));
Str.SetSize(StrSz);
if StrSz > 0 then MyBackupStream.ReadBuffer(Str.Memory^, StrSz);
SetString(S, PAnsiChar(Str.Memory), StrSz);
MyStringList.Text := String(S);
...
end;
或这个:
var
...
S: AnsiString;
begin
...
MyBackupStream.ReadBuffer(StrSz, SizeOf(Integer));
if StrSz > 0 then begin
SetLength(S, StrSz);
MyBackupStream.ReadBuffer(S[1], StrSz);
end;
MyStringList.Text := String(S);
...
end;
或这个:
var
...
Str: TStringStream;
begin
...
Str := TStringStream.Create;
try
MyBackupStream.ReadBuffer(StrSz, SizeOf(Integer));
if StrSz > 0 then Str.CopyFrom(MyBackupStream, StrSz);
MyStringList.Text := Str.DataString;
finally
Str.Free;
end;
...
end;
最后,您应该考虑将流数据更改为使用 UTF-8 而不是 Ansi,以获得更好的未来兼容性。两者在 D2009+SaveToStream()中LoadFromStream()都有一个可选TEncoding参数,UTF-8 是无损 Unicode 编码,而 Ansi 在 Ansi/Unicode 转换过程中可能会丢失数据。如果您现有的数据是 ASCII(AnsiChar#127 以上没有字符),那么 UTF-8 与 ASCII 100% 向后兼容。但是,如果数据是 Ansi(具有AnsiChar#127 以上的字符),那么您最好以某种方式更改您的流格式(添加标题/版本等),以便您可以区分旧格式和新格式,然后您可以加载使用 Ansi 的旧格式,使用 Unicode/UTF-8 保存/加载新格式。