gpt4 book ai didi

http - Delphi - 使用 Synapse 下载有进度的文件

转载 作者:可可西里 更新时间:2023-11-01 16:18:34 24 4
gpt4 key购买 nike

我使用 Synapse 已有一段时间了,主要是为了发送电子邮件。今天我正在创建一个简单的安装程序,并尝试通过 HTTP 下载应用程序 exe 文件。该文件大小约为 9 MB,因此我想向用户添加进度状态,但我不理解我找到的示例。这是我到目前为止得到的:

type
THookSocketStatus = Procedure(Sender: TObject; Reason: THookSocketReason; const Value: String) of Object;
CallBack = class
Class Procedure Status(Sender: TObject; Reason: THookSocketReason; const Value: String);
end;


Class Procedure CallBack.Status(Sender: TObject; Reason: THookSocketReason; const Value: String);
var
V: String;
Begin
V := GetEnumName(TypeInfo(THookSocketReason), Integer(Reason)) + ' ' + Value;
Form1.mem1.Lines.Add(V);
application.ProcessMessages;
end;

procedure TForm1.btn1Click(Sender: TObject);
var
HTTP: THTTPSend;
MSTM: TMemoryStream;
begin
Screen.Cursor := crHourGlass;
HTTP := THTTPSend.Create;
MSTM := TMemoryStream.Create;
Try
Try
HTTP.Sock.OnStatus := CallBack.Status;
If HTTP.HTTPMethod('GET', edt1.Text) Then
Begin
MSTM.Seek(0, soFromBeginning);
MSTM.CopyFrom(HTTP.Document, 0);
MSTM.SaveToFile(ExtractFilePath(Application.ExeName) + 'test.exe');
end;
Except
end;
Finally
MSTM.Free;
HTTP.Free;
Screen.Cursor := crDefault;
end;
end;

在这个简单的测试中我得到了这个结果:

HR_SocketClose
HR_ResolvingBegin www.website.com:80
HR_ResolvingEnd 176.102.295.18:80
HR_SocketCreate IPv4
HR_Connect www.website.com:80
HR_WriteCount 158
HR_CanRead
HR_ReadCount 288
HR_CanRead
HR_ReadCount 8192
HR_ReadCount 8192
HR_ReadCount 8192
HR_ReadCount 6720
HR_CanRead
HR_ReadCount 3299
.
.
.
HR_ReadCount 8192
HR_ReadCount 8192
HR_ReadCount 7828
HR_SocketClose
HR_SocketClose

请问,WriteCount 和 ReadCount 是什么意思?如何在开始下载之前获取总文件大小以设置进度条?

谢谢大家!

最佳答案

我遇到了同样的问题,通过扩展上面的代码找到了解决方案。文件长度可通过使用 header 信息获得,如上所示。

这是我的代码:

unit uhttpdownloader;


{$mode Delphi}{$H+}

interface

uses
Classes, SysUtils, httpsend, blcksock, typinfo;

//Interface for notifications about the progress
type
IProgress = interface
procedure ProgressNotification(Text: String; CurrentProgress : integer; MaxProgress : integer);
end;

type
{ THttpDownloader }

THttpDownloader = class
public
function DownloadHTTP(URL, TargetFile: string; ProgressMonitor : IProgress): Boolean;
private
Bytes : Integer;
MaxBytes : Integer;
HTTPSender: THTTPSend;
ProgressMonitor : IProgress;
procedure Status(Sender: TObject; Reason: THookSocketReason; const Value: String);
function GetSizeFromHeader(Header: String):integer;
end;

implementation

function THttpDownloader.DownloadHTTP(URL, TargetFile: string; ProgressMonitor : IProgress): Boolean;
var
HTTPGetResult: Boolean;
begin
Result := False;
Bytes:= 0;
MaxBytes:= -1;
Self.ProgressMonitor:= ProgressMonitor;

HTTPSender := THTTPSend.Create;
try
//add callback function for status updates
HTTPSender.Sock.OnStatus:= Status;
HTTPGetResult := HTTPSender.HTTPMethod('GET', URL);
if (HTTPSender.ResultCode >= 100) and (HTTPSender.ResultCode<=299) then begin
HTTPSender.Document.SaveToFile(TargetFile);
Result := True;
end;
finally
HTTPSender.Free;
end;
end;

//Callback function for status events
procedure THttpDownloader.Status(Sender: TObject; Reason: THookSocketReason; const Value: String);
var
V, currentHeader: String;
i: integer;
begin
//try to get filesize from headers
if (MaxBytes = -1) then
begin
for i:= 0 to HTTPSender.Headers.Count - 1 do
begin
currentHeader:= HTTPSender.Headers[i];
MaxBytes:= GetSizeFromHeader(currentHeader);
if MaxBytes <> -1 then break;
end;
end;

V := GetEnumName(TypeInfo(THookSocketReason), Integer(Reason)) + ' ' + Value;

//HR_ReadCount contains the number of bytes since the last event
if Reason = THookSocketReason.HR_ReadCount then
begin
Bytes:= Bytes + StrToInt(Value);
ProgressMonitor.ProgressNotification(V, Bytes, MaxBytes);
end;
end;

function THttpDownloader.GetSizeFromHeader(Header: String): integer;
var
item : TStringList;
begin
//the download size is contained in the header (e.g.: Content-Length: 3737722)
Result:= -1;

if Pos('Content-Length:', Header) <> 0 then
begin
item:= TStringList.Create();
item.Delimiter:= ':';
item.StrictDelimiter:=true;
item.DelimitedText:=Header;
if item.Count = 2 then
begin
Result:= StrToInt(Trim(item[1]));
end;
end;
end;
end.

完整的源代码和示例也可以在这里下载: http://andydunkel.net/lazarus/delphi/2015/09/09/lazarus_synapse_progress.html

安迪

关于http - Delphi - 使用 Synapse 下载有进度的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16345741/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com