我正在尝试使用indy10 http组件TIdHttp下载文件,同时获得进度,我刚刚在应用程序文件夹中设置了库,同时使用http URL的代码它可以工作和进步但是使用https它根本什么也没做它不会引发任何异常:/
with TIdHTTP.Create(nil) do
begin
IOHndl:=TIdSSLIOHandlerSocketOpenSSL.Create(nil);
Request.BasicAuthentication:=True;
HandleRedirects:=True;
IOHandler:=IOHndl;
OnWork:=FOnWork;
OnWorkBegin:=FOnWorkBegin;
OnWorkEnd:=FOnWorkEnd;
Get(FUrl,FStream);
end;
最好的问候
答案 0 :(得分:4)
首先,您必须创建一个小类来包装HTTP组件:
unit IdHTTPProgressU;
interface
uses
Classes, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, IdSSLOpenSSL;
{$M+}
type
TIdHTTPProgress = class(TIdHTTP)
private
FProgress: Integer;
FBytesToTransfer: Int64;
FOnChange: TNotifyEvent;
IOHndl: TIdSSLIOHandlerSocketOpenSSL;
procedure HTTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64);
procedure HTTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
procedure HTTPWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
procedure SetProgress(const Value: Integer);
procedure SetOnChange(const Value: TNotifyEvent);
public
Constructor Create(AOwner: TComponent);
procedure DownloadFile(const aFileUrl: string; const aDestinationFile: String);
published
property Progress: Integer read FProgress write SetProgress;
property BytesToTransfer: Int64 read FBytesToTransfer;
property OnChange: TNotifyEvent read FOnChange write SetOnChange;
end;
implementation
uses
Sysutils;
{ TIdHTTPProgress }
constructor TIdHTTPProgress.Create(AOwner: TComponent);
begin
inherited;
IOHndl := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
Request.BasicAuthentication := True;
HandleRedirects := True;
IOHandler := IOHndl;
ReadTimeout := 30000;
OnWork := HTTPWork;
OnWorkBegin := HTTPWorkBegin;
OnWorkEnd := HTTPWorkEnd;
end;
procedure TIdHTTPProgress.DownloadFile(const aFileUrl: string; const aDestinationFile: String);
var
LDestStream: TFileStream;
aPath: String;
begin
Progress := 0;
FBytesToTransfer := 0;
aPath := ExtractFilePath(aDestinationFile);
if aPath <> '' then
ForceDirectories(aPath);
LDestStream := TFileStream.Create(aDestinationFile, fmCreate);
try
Get(aFileUrl, LDestStream);
finally
FreeAndNil(LDestStream);
end;
end;
procedure TIdHTTPProgress.HTTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
begin
if BytesToTransfer = 0 then // No Update File
Exit;
Progress := Round((AWorkCount / BytesToTransfer) * 100);
end;
procedure TIdHTTPProgress.HTTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64);
begin
FBytesToTransfer := AWorkCountMax;
end;
procedure TIdHTTPProgress.HTTPWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
begin
FBytesToTransfer := 0;
Progress := 100;
end;
procedure TIdHTTPProgress.SetOnChance(const Value: TNotifyEvent);
begin
FOnChance := Value;
end;
procedure TIdHTTPProgress.SetProgress(const Value: Integer);
begin
FProgress := Value;
if Assigned(FOnChance) then
FOnChance(Self);
end;
end.
我不会详细介绍calss:只是说它可以包含TIdhttp组件并分配3个事件:OnBegin
,onWork
和OnEnd
方法DownloadFile
执行实际下载,
然后当你必须使用它时,你可以这样做:
将Button和PrograssBar放在空表格上。将IdHTTPProgressU
添加到使用列表中。
声明TIdHTTPProgress
和本地onChangeEvent
您的表单定义应该像这样:
type
TForm1 = class(TForm)
Button1: TButton;
ProgressBar1: TProgressBar;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
procedure IdHTTPProgressOnChange(Sender : TObject);
public
IdHTTPProgress: TIdHTTPProgress;
end;
然后你只需要实现这些方法:
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
IdHTTPProgress.OnChange := IdHTTPProgressOnChance;
IdHTTPProgress.OnChance := IdHTTPProgressOnChance;
IdHTTPProgress.DownloadFile('https://wordpress.org/latest.zip', 'latest.zip');
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
IdHTTPProgress := TIdHTTPProgress.Create(Self);
end;
procedure TForm1.IdHTTPProgressOnChance(Sender: TObject);
begin
ProgressBar1.Position := TIdHTTPProgress(Sender).Progress;
Application.ProcessMessages;
end;
多数民众赞成。试试吧。