将 TMemoryStream 转换为“String” 2009年在德尔福

发布于 2024-07-17 05:39:42 字数 556 浏览 8 评论 0原文

在 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?

We had the following code prior to 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;

How might we convert this code to support Unicode now with Delphi 2009?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

奶茶白久 2024-07-24 05:39:42

即使对于较旧的 Delphi 版本,您所拥有的代码也不必要地复杂。 毕竟,为什么获取流的字符串版本会强制重新分配流的内存?

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

这适用于所有 Delphi 版本,而不仅仅是 Delphi 2009。它在流为空时有效,没有任何特殊情况。 SetString 是一个未被充分重视的函数。

如果切换到 Delphi 2009 后流的内容没有更改为 Unicode,那么您应该改用此函数:

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

这相当于您的原始代码,但跳过特殊情况。

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.

演出会有结束 2024-07-24 05:39:42

或者也许您可以重构代码以直接使用 TStringStream? 您可以使用它代替 TMemoryStream (它们具有相同的接口),并且只需调用 myString := myStringStream.DataString; 即可将其“转换”为字符串。

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;

橙味迷妹 2024-07-24 05:39:42

一种“更干净”的方式可能是:

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;

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;
帅气尐潴 2024-07-24 05:39:42

我使用:

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测试过。

I use:

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;

It has been tested with Delphi XE7 only.

反差帅 2024-07-24 05:39:42

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

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

I have not upgraded yet, but my understanding is:

NewCapacity := (M.Size + 1) * SizeOf(Char);
无尽的现实 2024-07-24 05:39:42

有一个名为 TStringStream 的因素可以为您提供帮助。 。 您可以像这样加载另一个流的内容:

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

您现在可以进入字符串类型的系列,如下所示: data-string 属性包含系列...但不要尝试使用大型对象,例如如果您将一个大文件加载到某个文件流,然后将其复制到您自己的字符串流并努力生成它,因为它会占用大量内存!

希望有帮助

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

べ繥欢鉨o。 2024-07-24 05:39:42

您可以将其转换为正确大小的字符指针,然后简单地分配它:

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;

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;
请你别敷衍 2024-07-24 05:39:42

使用好的旧 StringList

function StreamToString (Stream : TStream; Encoding : TEncoding) : string;
begin
  var List := TStringList.Create;
  try
    List.LoadFromStream (Stream, Encoding);
    Result := List.Text;
  finally
    List.Free;
  end; 
end; 
  

using good old StringList

function StreamToString (Stream : TStream; Encoding : TEncoding) : string;
begin
  var List := TStringList.Create;
  try
    List.LoadFromStream (Stream, Encoding);
    Result := List.Text;
  finally
    List.Free;
  end; 
end; 
  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文