How to download a file with progress with IdHTTP via https

前端 未结 1 598
刺人心
刺人心 2021-02-06 17:59

I\'m trying to download a file using indy10 http components TIdHttp while getting the progress , I have just setted the libraries in the application folder while using the code

相关标签:
1条回答
  • 2021-02-06 18:36

    First you have to create a small class to wrap the HTTP component:

    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.
    

    I wont go in to details with the calss: Just say that it bacally wraps a TIdhttp component in and assign the 3 events: OnBegin, onWork and OnEnd

    The Method DownloadFile does the actually download,

    Then when you have to use it you could do like this:
    Place a Button and a PrograssBar on an empty form. Add IdHTTPProgressU to the uses list.

    Declare a vaiable of TIdHTTPProgress and a local onChangeEvent

    Your form definition should lokke like this:

    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;
    

    Then you just have to implement the methods:

        { 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;
    

    Thats about it. Give it at try.

    0 讨论(0)
提交回复
热议问题