Delphi使用THTTPClient实现异步下载
首先在接口部分需要引用System.Net.HttpClient类
uses System.Net.HttpClient,System.IOUtils;
初始化必需的变量参数
FClient: THTTPClient; //异步下载类 FGlobalStart: Cardinal; //全局计时 FAsyncResult: IAsyncResult; //set and get 异步调用的状态 FDownloadStream: TStream; //下载流
异步下载类的初始化:其中下方的ReceiveDataEvent方法表示响应下载的当前进度:滚动台、百分比等可视化内容可通过其展示给用户
FClient := THTTPClient.Create; //初始化 FClient.OnReceiveData := ReceiveDataEvent;//下载数据进度接收事件 FClient.SecureProtocols := [THTTPSecureProtocol.TLS1, THTTPSecureProtocol.TLS11, THTTPSecureProtocol.TLS12];//协议类型 可自定义
procedure ReceiveDataEvent(const Sender: TObject; AContentLength, AReadCount: Int64; var Abort: Boolean); var LTime: Cardinal; LSpeed: Integer; begin LTime := TThread.GetTickCount - FGlobalStart;//片段事件 if LTime = 0 then Exit; LSpeed := (AReadCount * 1000) div LTime; // TThread.Queue 将线程放入主线程main窗体执行 用于显示进度 TThread.Queue(nil, procedure begin ProgressBarDownload.Value := AReadCount; LabelGlobalSpeed.Caption := Format('Global speed: %d KB/s', [LSpeed div 1024]); end); end;
在窗体上放置了一个启动的button按钮,在buttononclick事件中调用SampleDownload方法。SampleDownload方法为实际的下载启动操作
procedure SampleDownload; var URL: string; LResponse: IHTTPResponse; LFileName: string; LSize: Int64; begin LFileName := EditFileName.Text; //下载文件存放地址 try URL := EditUrl.Text; //下载地址 LResponse := FClient.Head(URL); //获取请求头 LSize := LResponse.ContentLength; //判断请求头的大小 是否请求成功 Memo1.Lines.Add(Format('Head response: %d - %s', [LResponse.StatusCode, LResponse.StatusText]));//打印出请求状态 和 状态内容 LResponse := nil; //释放请求头内容 ProgressBarDownload.Maximum := LSize; //进度条的最大值 要注意的是vcl与fmx进度条maxium不同 ProgressBarDownload.Minimum := 0; //进度条起点 ProgressBarDownload.Value := 0; //进度条当前值 LabelGlobalSpeed.Caption := 'Download speed: 0 KB/s'; Memo1.Lines.Add(Format('Downloading: "%s" (%d Bytes) into "%s"', [EditFileName.Text, LSize, LFileName])); // Create the file that is going to be dowloaded FDownloadStream := TFileStream.Create(LFileName, fmCreate); //下载流初始化以及文件权限设置 FDownloadStream.Position := 0; //下载流从起点开始 初始化 // Start the download process FGlobalStart := TThread.GetTickCount; FAsyncResult := FClient.BeginGet(DoEndDownload, URL, FDownloadStream);//返回异步调用状态 以及 随时可控 可断 finally BStopDownload.Enabled := FAsyncResult <> nil; //判断异步调用状态 BStartDownload.Enabled := FAsyncResult = nil; //释放 end; end;
//接收下载的状态 包括自然下载成功或用户人为终止
procedure DoEndDownload(const AsyncResult: IAsyncResult); var LAsyncResponse: IHTTPResponse; begin try //判断异步调用的状态 LAsyncResponse := THTTPClient.EndAsyncHTTP(AsyncResult); //将此线程阻塞到主线程中去 在ui界面上告知用户操作状态 TThread.Synchronize(nil, procedure begin if AsyncResult.IsCancelled then Memo1.Lines.Add('Download Canceled') else begin Memo1.Lines.Add('Download Finished!'); Memo1.Lines.Add(Format('Status: %d - %s', [LAsyncResponse.StatusCode, LAsyncResponse.StatusText])); end; BStopDownload.Enabled := False; BStartDownload.Enabled := True; end); finally LAsyncResponse := nil; FreeandNil(FDownloadStream); end; end;
放置了一个停止的Button按钮,在buttononclick中调用FAsyncResult.Cancel;方法可终止下载操作。
完整代码如下:
unit DownloadForm; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Net.URLClient, System.Net.HttpClient, System.Net.HttpClientComponent, Vcl.ComCtrls, Vcl.StdCtrls, System.Types, Vcl.ExtCtrls; type TFormDownload = class(TForm) Panel1: TPanel; Label1: TLabel; Label2: TLabel; EditFileName: TEdit; EditUrl: TEdit; BStartDownload: TButton; LabelGlobalSpeed: TLabel; BStopDownload: TButton; Panel2: TPanel; Memo1: TMemo; ProgressBarDownload: TProgressBar; procedure BStartDownloadClick(Sender: TObject); procedure ReceiveDataEvent(const Sender: TObject; AContentLength: Int64; AReadCount: Int64; var Abort: Boolean); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure BStopDownloadClick(Sender: TObject); private { Private declarations } FClient: THTTPClient; FGlobalStart: Cardinal; FAsyncResult: IAsyncResult; FDownloadStream: TStream; procedure SampleDownload; procedure DoEndDownload(const AsyncResult: IAsyncResult); public { Public declarations } end; var FormDownload: TFormDownload; implementation uses System.IOUtils; {$R *.dfm} procedure TFormDownload.BStopDownloadClick(Sender: TObject); begin (Sender as TButton).Enabled := False; FAsyncResult.Cancel; end; procedure TFormDownload.DoEndDownload(const AsyncResult: IAsyncResult); var LAsyncResponse: IHTTPResponse; begin try LAsyncResponse := THTTPClient.EndAsyncHTTP(AsyncResult); TThread.Synchronize(nil, procedure begin if AsyncResult.IsCancelled then Memo1.Lines.Add('Download Canceled') else begin Memo1.Lines.Add('Download Finished!'); Memo1.Lines.Add(Format('Status: %d - %s', [LAsyncResponse.StatusCode, LAsyncResponse.StatusText])); end; BStopDownload.Enabled := False; BStartDownload.Enabled := True; end); finally LAsyncResponse := nil; FreeandNil(FDownloadStream); end; end; procedure TFormDownload.ReceiveDataEvent(const Sender: TObject; AContentLength, AReadCount: Int64; var Abort: Boolean); var LTime: Cardinal; LSpeed: Integer; begin LTime := TThread.GetTickCount - FGlobalStart; if LTime = 0 then Exit; LSpeed := (AReadCount * 1000) div LTime; TThread.Queue(nil, procedure begin ProgressBarDownload.Value := AReadCount; LabelGlobalSpeed.Caption := Format('Global speed: %d KB/s', [LSpeed div 1024]); end); end; procedure TFormDownload.FormCreate(Sender: TObject); begin FClient := THTTPClient.Create; FClient.OnReceiveData := ReceiveDataEvent; FClient.SecureProtocols := [THTTPSecureProtocol.TLS1, THTTPSecureProtocol.TLS11, THTTPSecureProtocol.TLS12]; end; procedure TFormDownload.FormDestroy(Sender: TObject); begin FDownloadStream.Free; FClient.Free; end; procedure TFormDownload.BStartDownloadClick(Sender: TObject); begin BStartDownload.Enabled := False; SampleDownload; end; procedure TFormDownload.SampleDownload; var URL: string; LResponse: IHTTPResponse; LFileName: string; LSize: Int64; begin LFileName := EditFileName.Text; try URL := EditUrl.Text; LResponse := FClient.Head(URL); LSize := LResponse.ContentLength; Memo1.Lines.Add(Format('Head response: %d - %s', [LResponse.StatusCode, LResponse.StatusText])); LResponse := nil; ProgressBarDownload.Maximum := LSize; ProgressBarDownload.Minimum := 0; ProgressBarDownload.Value := 0; LabelGlobalSpeed.Caption := 'Download speed: 0 KB/s'; Memo1.Lines.Add(Format('Downloading: "%s" (%d Bytes) into "%s"', [EditFileName.Text, LSize, LFileName])); // Create the file that is going to be dowloaded FDownloadStream := TFileStream.Create(LFileName, fmCreate); FDownloadStream.Position := 0; // Start the download process FGlobalStart := TThread.GetTickCount; FAsyncResult := FClient.BeginGet(DoEndDownload, URL, FDownloadStream); finally BStopDownload.Enabled := FAsyncResult <> nil; BStartDownload.Enabled := FAsyncResult = nil; end; end; end.
使用上述方法,便可使用Delphi完成异步下载~Delphi是真的强大~超级大爱
原文地址:https://www.cnblogs.com/ne1620/p/16454384.html