Delphi使用THTTPClient实现异步下载
首先在接口部分需要引用System.Net.HttpClient类
1 | uses System . Net . HttpClient,System . IOUtils; |
初始化必需的变量参数
1 2 3 4 | FClient: THTTPClient; //异步下载类 FGlobalStart: Cardinal ; //全局计时 FAsyncResult: IAsyncResult; //set and get 异步调用的状态 FDownloadStream: TStream; //下载流 |
异步下载类的初始化:其中下方的ReceiveDataEvent方法表示响应下载的当前进度:滚动台、百分比等可视化内容可通过其展示给用户
1 2 3 4 | FClient := THTTPClient . Create; //初始化 FClient . OnReceiveData := ReceiveDataEvent; //下载数据进度接收事件 FClient . SecureProtocols := [THTTPSecureProtocol . TLS1, THTTPSecureProtocol . TLS11, THTTPSecureProtocol . TLS12]; //协议类型 可自定义 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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方法为实际的下载启动操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | 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 ;<br><br> //接收下载的状态 包括自然下载成功或用户人为终止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;方法可终止下载操作。
完整代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~