33

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 をサポートするには、このコードをどのように変換すればよいでしょうか?

4

7 に答える 7

72

古いバージョンの 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;

これは元のコードと同等ですが、特殊なケースはスキップされます。

于 2009-04-09T08:30:31.750 に答える
20

または、コードをリファクタリングして、TStringStream を直接使用することはできますか? TMemoryStream の代わりに使用でき (同じインターフェイスを持っています)、 myString := myStringStream.DataString; を呼び出すだけで文字列に「変換」できます。

于 2009-04-09T05:51:17.717 に答える
15

「よりクリーンな」方法は次のとおりです。

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;
于 2009-04-09T14:30:56.173 に答える
6

私が使う:

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 のみでテストされています。

于 2014-12-31T01:33:43.097 に答える
2

まだアップグレードしていませんが、私の理解は次のとおりです。

NewCapacity := (M.Size + 1) * SizeOf(Char);
于 2009-04-09T03:31:02.607 に答える