使用新的THttpClient多线程下载文件
由 hubdog 于 星期日, 2021-01-03 10:53 发表
最新的THttpClient组件替代了TIdHttp,调用的都是各个平台的原生api,天然支持https,不需要额外部署ssl的库。
unit CMain; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts, FMX.TreeView, System.Generics.Collections, System.Net.HttpClient, System.Net.URLClient; type TFormMain = class(TForm) tvDownload: TTreeView; tiRoot: TTreeViewItem; tiVideo: TTreeViewItem; tiEat: TTreeViewItem; tiFat: TTreeViewItem; tiNG: TTreeViewItem; procedure FormCreate(Sender: TObject); procedure tiClick(Sender: TObject); private { Private declarations } FDownloadMap:TDictionary<string,TTreeViewItem>; public { Public declarations } procedure ReceiveDataEvent(const Sender: TObject; AContentLength: Int64; AReadCount: Int64; var AAbort: Boolean); end; var FormMain: TFormMain; implementation {$R *.fmx} procedure TFormMain.FormCreate(Sender: TObject); begin // FDownloadMap:=TObjectDictionary<string,TTreeViewItem>.Create; tiEat.TagString:='https://www.520kxs.com/ikanbook.apk'; tiFat.TagString:='http://www.flashavconverter.com/downloads/1.flv'; tiNG.TagString:='http://www.flashavconverter.com/downloads/232423.flv'; tvDownload.ExpandAll; end; procedure TFormMain.ReceiveDataEvent(const Sender: TObject; AContentLength, AReadCount: Int64; var AAbort: Boolean); var http:IUrlRequest; ti:TTreeViewItem; org:String; rate:Double; fileSize:Integer; begin http:=(Sender as THttpRequest) as IUrlRequest; ti:=FDownloadMap[http.URL.ToString]; fileSize:=AContentLength; org:=ti.Text.Split(['('])[0]; rate:=AReadCount*100/fileSize; TThread.Synchronize(nil, procedure begin ti.Text:=org+Format('(下载进度 %0.f)', [rate]); end); end; procedure TFormMain.tiClick(Sender: TObject); var Url:string; ti:TTreeViewItem; http:THTTPClient; AStream:TMemoryStream; org:string; begin // ti:= (Sender as TTreeViewItem); Url:=ti.TagString; if (Url<>'') and (ti.TagObject=nil) then begin http:=THTTPClient.Create(); http.OnReceiveData := ReceiveDataEvent; AStream:=TMemoryStream.Create; ti.TagObject:=http; FDownloadMap.Add(url, ti); //http.Tag:=NativeInt(ti); org:=ti.Text.Split(['('])[0]; TThread.CreateAnonymousThread( procedure begin try try http.Get(Url, AStream); except TThread.Synchronize(nil, procedure begin ti.Text:=org+'(下载失败)'; end ); Exit; end; TThread.Synchronize(nil, procedure begin ti.Text:=org+'(下载完成)'; end ); AStream.SaveToFile('d:/temp/'); finally AStream.Free; http.Free; end; end).Start; end; end; end.