我正在使用IdHttp从网上下载文件,如下所示:
var
MS: TMemoryStream;
procedure Test1;
var
Http: TIdHTTP;
begin
Http := TIdHTTP.Create(nil);
try
MS := TMemoryStream.Create;
try
Http.Get('http://www.test.com/test.exe', MS);
finally
MS.Free;
end;
finally
Http.Free;
end;
end;
因此,下载的文件/流(不知道如何发音)将在MS.Memory
。
好吧,我希望将MS.Memory
转换为或转换为字符串,反之亦然。
我已经尝试过Rob Kennedy在这个问题中发布的功能:Converting TMemoryStream to 'String' in Delphi 2009
但我刚收到字符串:“ MZP
”
任何人都可以帮助我吗?
答案 0 :(得分:4)
检查结果字符串的长度。我想该字符串包含所有二进制文件,但由于字符串体中的零,您无法将其视为ASCII字符串。 可执行文件的签名(第一个字节):4D 5A 90 00. ASCII符号:MZP#0(在我的情况下,P是ANSI Cyrillic,符号取决于代码页)。
答案 1 :(得分:1)
所有exe,dll文件conatin签名MZP#0 ... 对于pchar字符串(delphi中的大字符串)#0表示字符串的结尾,而调试检查器显示MZP。
如果保留流的原始长度,则可以访问所有数据。
答案 2 :(得分:1)
就像其他人建议的那样,将二进制dll转换为没有编码的字符串是没有意义的。但如果确实需要,可以使用:TStringStream类而不是TMemoryStream。 和TStringStream.DataString属性将获取字符串。 请再次注意,直接将二进制数据转换为字符串可能会导致未指定的重新连接。使用编码模式:例如:base64,十六进制字符串
答案 3 :(得分:1)
我曾经从Converting TMemoryStream to 'String' in Delphi 2009使用以下功能:
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;
在Http.Get('http://www.test.com/test.exe', MS);
之后,您可以使用:s:=StreamToString(MS);
s是字符串。
对我来说,它在Delphi 10.2上可以读取互联网上的pdf文件。我花了一个小时才找到这个解决方案。在Internet上找到的将内存流转换为字符串的所有功能都不适用于我。这是唯一有效的方法。正常的解决方案是:s:= {Http.Get('http://www.test.com/test.exe');
而不使用内存流作为中介。
答案 4 :(得分:0)
您可以使用TStringList类的LoadFromStream方法。
答案 5 :(得分:0)
使用中间TStrinStream的方法很慢,因为它将内存从一个位置复制到另一位置2次:
我建议不使用任何中间对象,而只是将内存复制1次直接到结果中。这是我的功能:
Function TryMemoryStreamToString(const MS: TMemoryStream; var s: string): Boolean;
begin
Result := False; if(MS=nil)then exit;
try
SetLength(s, MS.Size - MS.Position);
MS.Read(s[1], Length(s));
Result := True;
except
Result := False;
end;
end;
当然,您也可以直接将字符串作为结果返回:
Function MemoryStreamToStringDef(const MS: TMemoryStream; const ADefault: string = ''): string;
begin
if Assigned(MS)
then try
SetLength(Result, MS.Size - MS.Position);
MS.Read(Result[1], Length(Result));
except
Result := ADefault;
end
else Result := ADefault;
end;
请记住,从MemoryStream读取将在TMemoryStream.Position指向的任何地方开始。因此,请记住这一点,并确保它位于您想要的位置,例如,如果您一直想要整个内容,则在调用函数之前将其设置为流的开头:
var
MS : TMemorySTream;
s : string;
//(...)
MS.Position := 0;
s := MemoryStreamToStringDef(MS);
//(...)