delphi string unicode delphi-2009 memorystream

Conversión de TMemoryStream a ''Cadena'' en Delphi 2009



string unicode (5)

¿O quizás puede refactorizar su código para usar directamente un TStringStream directamente? Puede usarlo en lugar de TMemoryStream (tienen la misma interfaz) y puede ''convertirlo'' a una cadena simplemente llamando a myString: = myStringStream.DataString;

Teníamos el siguiente código antes de Delphi 2009:

<span style="font: 10pt Courier New;"><span class="pas1-reservedword">function</span><span class="pas1-space"> </span><span class="pas1-identifier">MemoryStreamToString(M:</span><span class="pas1-space"> </span><span class="pas1-identifier">TMemoryStream):</span><span class="pas1-space"> </span><span class="pas1-reservedword">String</span><span class="pas1-symbol">; </span><span class="pas1-reservedword">var </span><span class="pas1-space"> </span><span class="pas1-identifier">NewCapacity:</span><span class="pas1-space"> </span><span class="pas1-identifier">Longint; </span><span class="pas1-reservedword">begin </span><span class="pas1-space"> </span><span class="pas1-reservedword">if</span><span class="pas1-space"> </span><span class="pas1-symbol">(M.Size</span><span class="pas1-space"> </span><span class="pas1-symbol">=</span><span class="pas1-space"> </span><span class="pas1-number">0)</span><span class="pas1-space"> </span><span class="pas1-reservedword">or</span><span class="pas1-space"> </span><span class="pas1-symbol">(M.Memory</span><span class="pas1-space"> </span><span class="pas1-symbol">=</span><span class="pas1-space"> </span><span class="pas1-reservedword">nil</span><span class="pas1-symbol">)</span><span class="pas1-space"> </span><span class="pas1-reservedword">then </span><span class="pas1-space"> </span><span class="pas1-identifier">Result:=</span><span class="pas1-space"> </span><span class="pas1-string">'''' </span><span class="pas1-space"> </span><span class="pas1-reservedword">else </span><span class="pas1-space"> </span><span class="pas1-reservedword">begin </span><span class="pas1-space"> </span><span class="pas1-reservedword">if</span><span class="pas1-space"> </span><span class="pas1-identifier">TMemoryStreamProtected(M).Capacity</span><span class="pas1-space"> </span><span class="pas1-symbol">=</span><span class="pas1-space"> </span><span class="pas1-identifier">M.Size</span><span class="pas1-space"> </span><span class="pas1-reservedword">then </span><span class="pas1-space"> </span><span class="pas1-reservedword">begin </span><span class="pas1-space"> </span><span class="pas1-identifier">NewCapacity:=</span><span class="pas1-space"> </span><span class="pas1-identifier">M.Size+1; </span><span class="pas1-space"> </span><span class="pas1-identifier">TMemoryStreamProtected(M).Realloc(NewCapacity); </span><span class="pas1-space"> </span><span class="pas1-reservedword">end</span><span class="pas1-symbol">; </span><span class="pas1-space"> </span><span class="pas1-identifier">NullString(M.Memory^)[M.Size]:=</span><span class="pas1-space"> </span><span class="pas1-character">#0; </span><span class="pas1-space"> </span><span class="pas1-identifier">Result:=</span><span class="pas1-space"> </span><span class="pas1-identifier">StrPas(M.Memory); </span><span class="pas1-space"> </span><span class="pas1-reservedword">end</span><span class="pas1-symbol">; </span><span class="pas1-reservedword">end</span><span class="pas1-symbol">; </span></span>

¿Cómo podríamos convertir este código para soportar Unicode ahora con Delphi 2009?


El código que tienes es innecesariamente complejo, incluso para versiones anteriores de Delphi. ¿Por qué la búsqueda de la versión de cadena de una secuencia obliga a reasignar la memoria de la secuencia, después de todo?

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

Eso funciona en todas las versiones Delphi, no solo en Delphi 2009. Funciona cuando la transmisión está vacía sin ningún caso especial. SetString es una función poco apreciada.

Si el contenido de tu transmisión no cambia a Unicode con tu cambio a Delphi 2009, entonces debes usar esta función:

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

Eso es equivalente a su código original, pero omite los casos especiales.


No he actualizado aún, pero mi entendimiento es:

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


Una manera "más limpia" podría ser:

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;


Yo suelo:

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;

Ha sido probado solo con Delphi XE7.