Conversione di TMemoryStream in “String” in Delphi 2009

Abbiamo avuto il seguente codice prima di 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;  

Come possiamo convertire questo codice per supportare Unicode ora con Delphi 2009?

Il codice che hai è inutilmente complesso, anche per le versioni Delphi più vecchie. Perché, dopo aver recuperato la versione di stringa di un stream, la memoria del stream dovrebbe essere riallocata, dopo tutto?

 function MemoryStreamToString(M: TMemoryStream): string; begin SetString(Result, PChar(M.Memory), M.Size div SizeOf(Char)); end; 

Funziona in tutte le versioni di Delphi, non solo in Delphi 2009. Funziona quando lo stream è vuoto senza casi particolari. SetString è una funzione SetString .

Se i contenuti del tuo stream non stanno cambiando in Unicode con il tuo passaggio a Delphi 2009, allora dovresti usare questa funzione:

 function MemoryStreamToString(M: TMemoryStream): AnsiString; begin SetString(Result, PAnsiChar(M.Memory), M.Size); end; 

È equivalente al tuo codice originale, ma salta i casi speciali.

O forse puoi refactoring il codice per utilizzare direttamente un TStringStream direttamente? Puoi usarlo al posto di TMemoryStream (hanno la stessa interfaccia) e puoi “convertirlo” in una stringa semplicemente chiamando myString: = myStringStream.DataString;

Un modo “più pulito” potrebbe essere:

 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; 

Io uso:

 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; 

È stato testato solo con Delphi XE7.

Non ho ancora aggiornato, ma la mia comprensione è:

 NewCapacity := (M.Size + 1) * SizeOf(Char);