Enregistrer un fichier téléchargé via WinHTTP sur le disque, en utilisant Delphi XE
Une réponse à cette question a montré comment il est facile à utiliser WinHTTP par Type de Bibliothèque importations en delphi.
j'ai importé la bibliothèque de type pour WinHTTP, puis essayé d'écrire une fonction D'aide de téléchargement de fichier en utilisant cette api. Voilà où j'en suis:
Je n'arrive pas à trouver comment sauver la IWinHttpRequest.Responsiestream (déclaré OleVariant dans le fichier TLB) comme Stream, to disk.
// IWinHttpRequest is defined by importing type library of WinHTTP.
// Microsoft WinHTTP Services, version 5.1 (Version 5.1) C:Windowssystem32winhttp.dll
function Download(const url, filename: String): Boolean;
var
http: IWinHttpRequest;
wUrl: WideString;
fs:TFileStream;
FileStream:IStream;
sz,rd,wr:Int64;
begin
try
wUrl := url;
http := CoWinHttpRequest.Create;
http.open('GET', wurl, False);
http.send(EmptyParam);
FStatus := http.status; // 200=OK!
result := FStatus=200;
if result then
begin
fs := TFileStream.Create(filename, fmCreate, fmShareExclusive );
try
FileStream := TStreamAdapter.Create(fs, soReference) as IStream;
sz := http.ResponseStream.Size;
http.ResponseStream.CopyTo(FileStream,sz,rd,wr);
finally
FileStream := nil;
fs.Free;
end;
end;
except
result := false;
// do not raise exceptions.
end;
end;
extrait de WinHTTP_TLB.pas:
IWinHttpRequest = interface(IDispatch)
['{016FE2EC-B2C8-45F8-B23B-39E53A75396B}']
......
property ResponseStream: OleVariant read Get_ResponseStream;
mise à jour: je reçois maintenant une exception d'exécution sur les variantes ole, à l'appel à http.ResponseStream.CopyTo(...)
EOleError 'Variant does not reference an automation object'.
1 réponses
Warren, vous devez utiliser la classe AxCtrls.TOleStream
pour communiquer le flux de réponse avec le Classes.TFileStream
quelque chose comme ça
IWinHttpRequest.ResponseStream -> TOleStream -> TFileStream
vérifier ce code d'échantillon
{$APPTYPE CONSOLE}
uses
Variants,
ActiveX,
Classes,
AxCtrls,
WinHttp_TLB,
SysUtils;
function Download(const url, filename: String): Boolean;
var
http: IWinHttpRequest;
wUrl: WideString;
fs:TFileStream;
HttpStream :IStream;
sz,rd,wr:Int64;
FStatus : Integer;
OleStream: TOleStream;
begin
try
wUrl := url;
http := CoWinHttpRequest.Create;
http.open('GET', wurl, False);
http.send(EmptyParam);
FStatus := http.status; // 200=OK!
result := FStatus=200;
if result then
begin
HttpStream:=IUnknown(http.ResponseStream) as IStream;
OleStream:= TOleStream.Create(HttpStream);
try
fs:= TFileStream.Create(FileName, fmCreate);
try
OleStream.Position:= 0;
fs.CopyFrom(OleStream, OleStream.Size);
finally
fs.Free;
end;
finally
OleStream.Free;
end;
end;
except
result := false;
// do not raise exceptions.
end;
end;
begin
try
Download('http://foo.html','C:\Foo\anyfile.foo');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.