Writing strings to TMemoryStream
35,321
When you use
Stream.Write(Str[1], StrLen);
you're writing first StrLen
bytes to the stream. But the (unicode)string data is actually StrLen * SizeOf(Char)
bytes (you have to take the size of the char type into account). So following should work:
Stream.Write(Str[1], StrLen * SizeOf(Str[1]));
Same when reading data back from stream.
Author by
JakeSays
Updated on July 09, 2022Comments
-
JakeSays almost 2 years
I have read alot of discussions on here regarding writing strings to a TMemoryStream and saving to file and reading the strings back in to TMemoryStream
I dont know what I have done wrong here, but either my SaveData or my LoadData is wrong. I can check the value of Title before I call SaveData and it holds what I expect. However, when I call LoadData and check the value of Title, it is garbage. Can anyone tell me what I have done wrong please
procedure SaveData(FileName: TFileName); var MemStr: TMemoryStream; Title: String; begin MemStr:= TMemoryStream.Create; try MemStr.Seek(0, soFromBeginning); WriteStreamStr( MemStr, TItle ); MemStr.SaveToFile(FileName); finally MemStr.Free; end; end; procedure LoadData(FileName: TFileName); var MemStr: TMemoryStream; Title: String; begin MemStr:= TMemoryStream.Create; try MemStr.LoadFromFile(FileName); MemStr.Seek(0, soFromBeginning); Title := ReadStreamStr( MemStr ); finally MemStr.Free; end; end; procedure WriteStreamInt(Stream : TStream; Num : integer); {writes an integer to the stream} begin Stream.WriteBuffer(Num, SizeOf(Integer)); end; procedure WriteStreamStr(Stream : TStream; Str : string); {writes a string to the stream} var StrLen : integer; begin {get length of string} StrLen := Length(Str); {write length of string} WriteStreamInt(Stream, StrLen); if StrLen > 0 then {write characters} Stream.Write(Str[1], StrLen); end; function ReadStreamInt(Stream : TStream) : integer; {returns an integer from stream} begin Stream.ReadBuffer(Result, SizeOf(Integer)); end; function ReadStreamStr(Stream : TStream) : string; {returns a string from the stream} var LenStr : integer; begin Result := ''; {get length of string} LenStr := ReadStreamInt(Stream); {set string to get memory} SetLength(Result, LenStr); {read characters} Stream.Read(Result[1], LenStr); end;
-
David Heffernan about 11 years
ByteLength(Str)
exists for this