string 在 Delphi 2009 中将 TMemoryStream 转换为“字符串”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/732666/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting TMemoryStream to 'String' in Delphi 2009
提问by dmillam
We had the following code prior to Delphi 2009:
在 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?
我们现在如何使用 Delphi 2009 转换此代码以支持 Unicode?
回答by Rob Kennedy
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?
您拥有的代码过于复杂,即使对于较旧的 Delphi 版本也是如此。毕竟,为什么要获取流的字符串版本会强制重新分配流的内存?
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.
这适用于所有 Delphi 版本,而不仅仅是 Delphi 2009。它在流为空时工作,没有任何特殊情况。SetString
是一个被低估的功能。
If the contents of your stream aren't changing to Unicode with your switch to Delphi 2009, then you should use this function instead:
如果您切换到 Delphi 2009 时流的内容没有更改为 Unicode,那么您应该改用此函数:
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.
这相当于您的原始代码,但跳过了特殊情况。
回答by John Thomas
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;
或者您可以重构您的代码以直接使用 TStringStream ?您可以使用它代替 TMemoryStream(它们具有相同的接口),并且您可以通过简单地调用 myString := myStringStream.DataString; 将其“转换”为字符串。
回答by Nick Hodges
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;
回答by Ivelin Nikolaev
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.
它仅在 Delphi XE7 上进行了测试。
回答by Techpromint
There's a factor called TStringStream
that will be able to assist you. . .you can load the contents of another flow like that:
有一个因素TStringStream
可以帮助你。. .你可以像这样加载另一个流的内容:
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
希望有帮助
回答by Loren Pechtel
I have not upgraded yet, but my understanding is:
我还没有升级,但我的理解是:
NewCapacity := (M.Size + 1) * SizeOf(Char);
回答by The Bitman
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;