在 Delphi 2009中将TMemoryStream转换为“String”

ejk8hzay  于 2024-01-07  发布在  其他
关注(0)|答案(8)|浏览(290)

在 Delphi 2009之前,我们有以下代码:

  1. function MemoryStreamToString(M : TMemoryStream): String;
  2. var
  3. NewCapacity: Longint;
  4. begin
  5. if (M.Size = > 0) or (M.Memory = nil) then
  6. Result:= ''
  7. else
  8. begin
  9. if TMemoryStreamProtected(M).Capacity = M.Size then
  10. begin
  11. NewCapacity:= M.Size+1;
  12. TMemoryStreamProtected(M).Realloc(NewCapacity);
  13. end;
  14. NullString(M.Memory^)[M.Size]:= #0;
  15. Result:= StrPas(M.Memory);
  16. end;
  17. end;

字符串
我们如何在 Delphi 2009中转换这些代码以支持Unicode?

q8l4jmvw

q8l4jmvw1#

你的代码是不必要的复杂,即使是老的 Delphi 版本。为什么要获取流的字符串版本强制重新分配流的内存呢?

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

字符串
这适用于所有 Delphi 版本,而不仅仅是 Delphi 2009。它在流为空时工作,没有任何特殊情况。SetString是一个被低估的函数。
如果切换到 Delphi 2009后流的内容没有更改为Unicode,那么你应该使用这个函数:

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


这与您的原始代码等效,但跳过了特殊情况。

展开查看全部
7kqas0il

7kqas0il2#

或者你可以重构你的代码来直接使用TStringStream?你可以使用它来代替TMemoryStream(它们有相同的接口),你可以通过简单地调用myString:= myStringStream.DataString;

ecfsfe2w

ecfsfe2w3#

一个“更干净”的方法可能是:

  1. function StreamToString(aStream: TStream): string;
  2. var
  3. SS: TStringStream;
  4. begin
  5. if aStream <> nil then
  6. begin
  7. SS := TStringStream.Create('');
  8. try
  9. SS.CopyFrom(aStream, 0); // No need to position at 0 nor provide size
  10. Result := SS.DataString;
  11. finally
  12. SS.Free;
  13. end;
  14. end else
  15. begin
  16. Result := '';
  17. end;
  18. end;

字符串

展开查看全部
9ceoxa92

9ceoxa924#

我用途:

  1. function StreamToString(const Stream: TStream; const Encoding: TEncoding): string;
  2. var
  3. StringBytes: TBytes;
  4. begin
  5. Stream.Position := 0;
  6. SetLength(StringBytes, Stream.Size);
  7. Stream.ReadBuffer(StringBytes, Stream.Size);
  8. Result := Encoding.GetString(StringBytes);
  9. end;

字符串
它已经测试了 Delphi XE7只。

mkh04yzy

mkh04yzy5#

我还没有升级,但我的理解是:

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

字符串

nkoocmlb

nkoocmlb6#

有一个名为TStringStream的因子可以帮助你.你可以像这样加载另一个流的内容:

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

字符串
你现在可以进入一个String类型的序列,比如:data-string属性包含了序列.但是不要尝试使用大对象,比如你加载一个巨大的文件到一些文件列表中,然后将其复制到你自己的stringstream中,并努力产生它,因为它会占用很多内存!
希望有帮助

yquaqz18

yquaqz187#

你可以把它转换成正确大小的字符指针,然后简单地赋值:

  1. procedure getMemoryStreamAsString( aMS_ : TMemoryStream );
  2. var
  3. ws : widestring; // in newer Delphi it can be string
  4. ans : ansistring;
  5. begin
  6. ws := pwidechar( aMS_.memory );
  7. // OR
  8. ans := pansichar( aMS_.memory );
  9. end;

字符串

pinkon5k

pinkon5k8#

使用良好的旧StringList

  1. function StreamToString (Stream : TStream; Encoding : TEncoding) : string;
  2. begin
  3. var List := TStringList.Create;
  4. try
  5. List.LoadFromStream (Stream, Encoding);
  6. Result := List.Text;
  7. finally
  8. List.Free;
  9. end;
  10. end;

字符串

相关问题