文字のInteger
前に書かれているのはバイト数ですが、代わりに文字数ReadStreamStr()
として解釈しています。D2007 以前では、Ansi は正常に動作します。しかし、D2009 以降では、Unicode は機能しません。D2009+ を使用していると仮定すると、本来の2 倍のメモリが割り当てられますが、その半分だけを埋め、残りの半分は初期化しないままにしておきます。読むときは考慮していません(ただし、書くときは考慮します)。string
string
ReadStreamStr()
SizeOf(Char)
ByteLength()
これを試して:
function ReadStreamStr(Stream: TStream): string;
{ returns a string from the stream }
var
LenStr: Integer;
LeftOver: array[0..SizeOf(Char)-1] of Byte;
begin
Result := '';
{ get length of string }
LenStr := ReadStreamInt(Stream);
{ set string to get memory }
SetLength(Result, LenStr div SizeOf(Char));
if LenStr > 0 then begin
{ read characters }
Stream.ReadBuffer(Result[1], LenStr);
{ just in case the length was not even }
LenStr := LenStr mod SizeOf(Char);
if LenStr > 0 then
Stream.ReadBuffer(LeftOver[0], LenStr);
end;
end;
または:
function ReadStreamStr(Stream: TStream): string;
{ returns a string from the stream }
var
LenStr: Integer;
Buf: TBytes;
begin
Result := '';
{ get length of string }
LenStr := ReadStreamInt(Stream);
if LenStr > 0 then begin
{ get memory }
SetLength(Buf, LenStr);
{ read characters }
Stream.ReadBuffer(Buf[1], LenStr);
{ convert to string }
Result := TEncoding.Unicode.GetString(Buf);
end;
end;
いずれにせよ、ストリーム データが D2007 以前で書き込まれ、D2009 以降で読み取られた場合、このコードはそのままでは機能しないことに注意してください。TBytes
アプローチに行く必要がありますがTEncoding
、 などのデコードに適したものを使用してくださいTEncoding.Default
。
個人的には、代わりに文字列を最初から UTF-8 として読み書きすることを選択したでしょう。
function ReadStreamStr(Stream: TStream): UTF8String;
{ 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);
if LenStr > 0 then
{ read characters }
Stream.Read(PAnsiChar(Result)^, LenStr);
end;
procedure WriteStreamStr(Stream: TStream; const Str: UTF8tring);
{ 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(PAnsiChar(Str)^, StrLen);
end;