在 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?
您拥有的代码不必要地复杂,即使对于较旧的 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;
这相当于您的原始代码,但跳过特殊情况。
或者也许您可以重构代码以直接使用 TStringStream?您可以使用它代替 TMemoryStream (它们具有相同的接口),并且只需调用 myString := myStringStream.DataString; 即可将其“转换”为字符串。
“更干净”的方式可能是:
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;
我用:
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上进行过测试。
我还没有升级,但我的理解是:
NewCapacity := (M.Size + 1) * SizeOf(Char);
有一个名为
TStringStream
的因素可以为您提供帮助。 。 .您可以像这样加载另一个流的内容:
var StringStream: TStringStream;
begin StringStream := TStringStream.Create('');
StringStream.CopyFrom(OtherStream, OtherStream.Size);
end;
您现在可以进入字符串类型的系列,如下所示:数据字符串属性包含系列...但不要尝试使用大型对象,例如将一个大文件加载到某个文件流时将其复制到您自己的字符串流并努力生成它,因为它会占用大量内存!
希望有帮助
您可以将其转换为正确大小的字符指针,然后简单地分配它:
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;
使用古老的 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;