随着Delphi 10.2.3的发布,随之带来更稳定、更完善的版本。今天借官方的例子,解读一下如何实现Http异步下载并显示下载进度。

使用的核心组件是THttpClient,首先建立一个THttpClient对象FClient,用他来执行下载任务。
procedure TFormDownloadDemo.FormCreate(Sender: TObject);
begin
FClient := THTTPClient.Create;
FClient.OnReceiveData := ReceiveDataEvent;
end;

我们看到,这里为FClient实现了OnReceiveData事件,目的用来显示下载进度,注意这个事件在异步执行Http下载时,是在线程中执行的。来看一下具体的实现代码:

procedure TFormDownloadDemo.ReceiveDataEvent(const Sender: TObject; AContentLength, AReadCount: Int64;
var Abort: Boolean);
var
LTime: Cardinal;
LSpeed: Integer;
begin
LTime := TThread.GetTickCount - FGlobalStart;//计算用时
LSpeed := (AReadCount * ) div LTime;//计算下载速度
TThread.Queue(nil,
procedure
begin
ProgressBarDownload.Value := AReadCount;//显示下载进度
LabelGlobalSpeed.Text := Format('Global speed: %d KB/s', [LSpeed div ]);//显示下载速度
end);
end;
AContentLength:下载内容的长度
AReadCount:已经下载的字节数
在这个事件中,计算每秒下载字节数,并用ProgressBarDownload可视组件来显示进度。
因为这个事件在线程中执行,所以同步界面上的ProgressBarDownload进度条时,用了TThread.Queue同步主线程。
 
接下来,实现具体的下载方法,并用一个按钮来执行这个方法,执行下载任务:
procedure TFormDownloadDemo.SampleDownload;
var
URL: string;
LResponse: IHTTPResponse;
LFileName: string;
LSize: Int64;
begin
LFileName := TPath.Combine(TPath.GetDocumentsPath, EditFileName.Text);//本地保存的文件地址
try
URL := EditURL.Text;//文件的URL地址 LResponse := FClient.Head(URL);//取得IHTTPResponse接口,通过该接口获得下载文件的长度
LSize := LResponse.ContentLength;//求出下载内容的长度
Memo1.Lines.Add(Format('Head response: %d - %s', [LResponse.StatusCode, LResponse.StatusText]));
LResponse := nil; ProgressBarDownload.Max := LSize;//设置进度条的最大值
ProgressBarDownload.Min := ;
ProgressBarDownload.Value := ;
LabelGlobalSpeed.Text := 'Global speed: 0 KB/s'; Memo1.Lines.Add(Format('Downloading: "%s" (%d Bytes) into "%s"' , [EditFileName.Text, LSize, LFileName])); // 建立一个文件流FDownloadStream,准备用于保存下载内容
FDownloadStream := TFileStream.Create(LFileName, fmCreate);//建立下载文件流
FDownloadStream.Position := ; FGlobalStart := TThread.GetTickCount;//取开始下载时间,用于计算下载速度 // 开始下载
FAsyncResult := FClient.BeginGet(DoEndDownload, URL, FDownloadStream); finally
BStopDownload.Enabled := FAsyncResult <> nil;//下载过程中允许中止下载
BStartDownload.Enabled := FAsyncResult = nil;//下载完成后允许开始下载
end;
end;
上面对下载方法进行了注释,但还有必要说一下这个具体的下载调用所要实现的目的:
 
FAsyncResult := FClient.BeginGet(DoEndDownload, URL, FDownloadStream);
 
我们看到,用FClient.BeginGet执行下载,同时传进去三个参数:
DoEndDownload:一个方法,下载完成后调用
URL:下载内容的URL
FDownLoadStream:保存下载内容的文件流。
 
重点在于DoEndDownload方法的实现:
procedure TFormDownloadDemo.DoEndDownload(const AsyncResult: IAsyncResult);
var
LAsyncResponse: IHTTPResponse;
begin
try
LAsyncResponse := THTTPClient.EndAsyncHTTP(AsyncResult);//通过传进来的参数,取得异步响应接口
TThread.Synchronize(nil,
procedure
begin
Memo1.Lines.Add('Download Finished!');
Memo1.Lines.Add(Format('Status: %d - %s', [LAsyncResponse.StatusCode, LAsyncResponse.StatusText]));
end);
finally
LAsyncResponse := nil;
FreeandNil(FDownloadStream);
BStopDownload.Enabled := False;
BStartDownload.Enabled := True;
end;
end;
首先这个方法,要声明成下面这样:
procedure (const ASyncResult: IAsyncResult);
然后我们看到,在具体的实现中,使用了传进来的参数ASyncResult,取得下载后接口LAsyncResponse,并通过该接口,进一步取得下载后的信息。
然后做的第二件事是释放保存下载的文件流FDownloadStream,最后设置开始下载按与中止下载按钮的状态。
同样,我们也看到,这里使用了TThread.Synchronize来同步界面,那说明这个方法也是在线程中执行的。
 
好了,在线程中下载文件并在界面上显示下载进度的整个过程基本就说完了。具体的例子代码在
C:\Users\Public\Documents\Embarcadero\Studio\19.0\Samples\Object Pascal\RTL\HttpAsyncDownload
这个例子是哪一个版本支持的,我也记不清,反正今天看到,全当10.2.3带的好了,其实这已不重要,重要的是,参考他来实现自己的http异步下载!
 
众所周知,这是一个跨平台的版本,同样的实现,可同时用于Android,IOS,Windows,OSX,Linux...这才是真正让人兴奋的事情。现在,我要集成到我的项目中去了...
 

Delphi10.2.3利用THttpClient实现http异步下载的更多相关文章

  1. 一个简单的利用 WebClient 异步下载的示例(一)

    继上一篇文章 一个简单的利用 HttpClient 异步下载的示例 ,我们知道不管是 HttpClient,还算 WebClient,都不建议每次调用都 new HttpClient,或 new We ...

  2. [.NET] 利用 async & await 的异步编程

    利用 async & await 的异步编程 [博主]反骨仔 [出处]http://www.cnblogs.com/liqingwen/p/5922573.html  目录 异步编程的简介 异 ...

  3. [.NET] 利用 async & await 进行异步 IO 操作

    利用 async & await 进行异步 IO 操作 [博主]反骨仔 [出处]http://www.cnblogs.com/liqingwen/p/6082673.html  序 上次,博主 ...

  4. 利用 async & await 的异步编程

    走进异步编程的世界 - 开始接触 async/await 利用 async & await 的异步编程 async 的三大返回类型 公司技术需求备忘录

  5. 教你50招提升ASP.NET性能(二十二):利用.NET 4.5异步结构

    (40)Take advantage of .NET 4.5 async constructs 招数40: 利用.NET 4.5异步结构 With the arrival of .NET 4.5, w ...

  6. 利用jquery.form实现异步上传文件

    实现原理 目前需要在一个页面实现多个地方调用上传控件上传文件,并且必须是异步上传.思考半天,想到通过创建动态表单包裹上传文件域,利用jquery.form实现异步提交表单,从而达到异步上传的目的,在上 ...

  7. 一个简单的利用 WebClient 异步下载的示例(三)

    继续上一篇 一个简单的利用 WebClient 异步下载的示例(二) 后,继续优化它. 1. 直接贴代码了: DownloadEntry: public class DownloadEntry { p ...

  8. 一个简单的利用 WebClient 异步下载的示例(二)

    继上一篇 一个简单的利用 WebClient 异步下载的示例(一) 后,我想把核心的处理提取出来,成 SkyWebClient,如下: 1. SkyWebClient 该构造函数中 downloadC ...

  9. 一个简单的利用 HttpClient 异步下载的示例

    可能你还会喜欢 一个简单的利用 WebClient 异步下载的示例  ,且代码更加新. 1. 定义自己的 HttpClient 类. using System; using System.Collec ...

随机推荐

  1. Python Flask,cookie,session ,设置、获取、删除

    使用Response类的set_cookie()方法可以设置cookie: Response.set_cookie( key, //键 value='', //值 max_age=None, //秒为 ...

  2. java的JDBC驱动使用链接数据库

    1.    import java.sql.*; 2 .    导入所需要的数据库的jar包,如oracle/informix的 3. String sql = "select * from ...

  3. 一百一十七:CMS系统之注册页面对接短信验证码

    from flask import Blueprint, requestfrom exts import alidayufrom utils import restfulfrom utils.capt ...

  4. [Hadoop] Yarn & k8s

    写在前面 一.大数据全栈 头两节讲完HDFS & MapReduce,这一部分聊一聊它们之间的“人物关系”. 其中也讨论下k8s的学习必要性. Ref: [Distributed ML] Yi ...

  5. JAVA正则表达式 Pattern和Matcher类

    java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包. 1.简介:  java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包. ...

  6. R语言与概率统计(三) 多元统计分析(下)广义线性回归

    广义线性回归 > life<-data.frame( + X1=c(2.5, 173, 119, 10, 502, 4, 14.4, 2, 40, 6.6, + 21.4, 2.8, 2. ...

  7. 第一个React Native项目

    1>下图操作创建第一个React Native项目: 用Xcode运行界面如下: 记住: 在使用项目文件期间,终端记住不要关闭的哟!!! 改变了程序代码,需要刷新运行,使用快捷键: Comman ...

  8. lumen返回网站base url

    可以使用全局帮助函数url() echo url(); //输出http://test.domain.com

  9. XLSX.js 导出Excel demo

    GitHub:https://github.com/SheetJS/js-xlsx 一个js操作Excel的工具,如下代码,很方便的就将json数据导出为Excel文件. 使用示例: //json 数 ...

  10. OpenCV图像旋转

    图像旋转是指图像按照某个位置转动一定角度的过程,旋转中图像仍保持这原始尺寸.图像旋转后图像的水平对称轴.垂直对称轴及中心坐标原点都可能会发生变换,因此需要对图像旋转中的坐标进行相应转换. 如下图: 假 ...