使用MyStringList.LoadFromStream(Str)
而不是MyStringList.Text := PChar( Str.Memory)
.
首先,您的TStream
数据不是以空值结尾的,但是使用PChar
您的方式需要一个空值终止符(您可以使用SetString()
字符串变量来解决这个问题)。
其次,从 D2009 开始,String
现在是UnicodeString
代替,AnsiString
现在PChar
是PWideChar
代替PAnsiChar
. 您的TStream
数据是 Ansi 而不是 Unicode(即使在 D2009+ 中,因为SaveToStream()
默认使用TEncoding.Default
Ansi 来编码流数据),因此将数据转换为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 保存/加载新格式。