Converting TMemoryStream to 'String' in Delphi 2009

后端 未结 7 904
南方客
南方客 2020-11-28 05:52

We had the following code prior to Delphi 2009:

function MemoryStreamToString(M : TMemoryStream): String;
var
    NewCapacity: Longint;
begin
    if (M.Size          


        
相关标签:
7条回答
  • 2020-11-28 06:15

    There's a factor called TStringStream that will be able to assist you. . .you can load the contents of another flow like that:

    var StringStream: TStringStream; 
    begin StringStream := TStringStream.Create(''); 
    StringStream.CopyFrom(OtherStream, OtherStream.Size); 
    end;
    

    You can now get into the series for a String kind such as this: The data-string property comprises the series... but do not try so with large objects such as in the event that you load a huge file to some filestream then copy this to your own stringstream and make an effort to produce it cause it arranges a lot of memory!

    Hope that helps

    0 讨论(0)
  • 2020-11-28 06:19

    The code you have is unnecessarily complex, even for older Delphi versions. Why should fetching the string version of a stream force the stream's memory to be reallocated, after all?

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

    That works in all Delphi versions, not just Delphi 2009. It works when the stream is empty without any special case. SetString is an under-appreciated function.

    If the contents of your stream aren't changing to Unicode with your switch to Delphi 2009, then you should use this function instead:

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

    That's equivalent to your original code, but skips the special cases.

    0 讨论(0)
  • 2020-11-28 06:20

    A "cleaner" way might be:

    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;
    
    0 讨论(0)
  • 2020-11-28 06:23

    Or perhaps you can refactor your code to use directly a TStringStream directly? You can use it instead of TMemoryStream (they have the same interface) and you can 'convert' it to a string by simply calling myString := myStringStream.DataString;

    0 讨论(0)
  • 2020-11-28 06:23

    I have not upgraded yet, but my understanding is:

    NewCapacity := (M.Size + 1) * SizeOf(Char);
    
    0 讨论(0)
  • 2020-11-28 06:29

    You can cast it into the right sized character pointer and just simple assign it:

    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;
    
    0 讨论(0)
提交回复
热议问题