Delphi 2009より前のバージョンには次のコードがありました。
function MemoryStreamToString(M : TMemoryStream): String;
var
NewCapacity: Longint;
begin
if (M.Size = > 0) or (M.Memory = nil) then
Result:= ''
else
begin
if TMemoryStreamProtected(M).Capacity = M.Size then
begin
NewCapacity:= M.Size+1;
TMemoryStreamProtected(M).Realloc(NewCapacity);
end;
NullString(M.Memory^)[M.Size]:= #0;
Result:= StrPas(M.Memory);
end;
end;
Delphi 2009でUnicodeをサポートするためにこのコードをどのように変換できますか?
Delphiの古いバージョンであっても、コードは不必要に複雑です。なぜストリームの文字列バージョンを取得すると、ストリームのメモリが強制的に再割り当てされるのですか?
function MemoryStreamToString(M: TMemoryStream): string;
begin
SetString(Result, PChar(M.Memory), M.Size div SizeOf(Char));
end;
これは、Delphi 2009だけでなく、すべてのDelphiバージョンで機能します。特別な場合を除き、ストリームが空のときに機能します。 SetString
は過小評価されている関数です。
Delphi 2009への切り替えでストリームのコンテンツがUnicodeに変更されない場合は、代わりにこの関数を使用する必要があります。
function MemoryStreamToString(M: TMemoryStream): AnsiString;
begin
SetString(Result, PAnsiChar(M.Memory), M.Size);
end;
これは元のコードと同等ですが、特殊なケースはスキップします。
または、TStringStreamを直接使用するようにコードをリファクタリングできますか? TMemoryStreamの代わりに使用でき(同じインターフェイスを持っています)、myStringを呼び出すだけで文字列に「変換」できます:= myStringStream.DataString;
「クリーナー」の方法は次のとおりです。
function StreamToString(aStream: TStream): string;
var
SS: TStringStream;
begin
if aStream <> nil then
begin
SS := TStringStream.Create('');
try
SS.CopyFrom(aStream, 0); // No need to position at 0 nor provide size
Result := SS.DataString;
finally
SS.Free;
end;
end else
begin
Result := '';
end;
end;
私が使う:
function StreamToString(const Stream: TStream; const Encoding: TEncoding): string;
var
StringBytes: TBytes;
begin
Stream.Position := 0;
SetLength(StringBytes, Stream.Size);
Stream.ReadBuffer(StringBytes, Stream.Size);
Result := Encoding.GetString(StringBytes);
end;
Delphi XE7でのみテストされています。
まだアップグレードしていませんが、私の理解は:
NewCapacity := (M.Size + 1) * SizeOf(Char);
あなたを助けることができるTStringStream
と呼ばれる要因があります。 。次のような別のフローのコンテンツをロードできます。
var StringStream: TStringStream;
begin StringStream := TStringStream.Create('');
StringStream.CopyFrom(OtherStream, OtherStream.Size);
end;
これで、次のような文字列の種類のシリーズに入ることができます:data-stringプロパティはシリーズで構成されていますが、巨大なファイルをファイルストリームにロードしてコピーするイベントなどの大きなオブジェクトではそうしないでくださいこれを独自の文字列ストリームに追加し、それを生成するために努力して、大量のメモリを配置します!
役立つことを願っています
適切なサイズの文字ポインターにキャストして、単純に割り当てることができます。
procedure getMemoryStreamAsString( aMS_ : TMemoryStream );
var
ws : widestring; // in newer Delphi it can be string
ans : ansistring;
begin
ws := pwidechar( aMS_.memory );
// OR
ans := pansichar( aMS_.memory );
end;