dicas show delphi

DICAS

Visite a biblioteca de dicas da comunidade.

Saiba mais
sombra
Artigos Show Delphi

ARTIGOS

Abordagens detalhadas sobre assuntos diversos.

Saiba mais
sombra
iniciantes show delphi

INICIANTES

Aprenda a programar de um modo simples e fácil.

Saiba mais
sombra
downloads show delphi

DOWNLOADS

Acesse os materiais exclusivos aos membros.

Saiba mais
sombra
voltar

PARA QUEM GOSTA DE DELPHI

Como fazer Download de Arquivos com Progresso do andamento?

Fala galera do Show Delphi, tudo beleza?

Hoje estava precisando implementar nos meus sistemas um mecanismo para baixar arquivos.

Então pesquisando vi que podia fazer isso utilizando o TIDHttp, que é um componente do Indy que já acompanha o Delphi por padrão e também é possível instalar no Lazarus gratuitamente.

Legal, basicamente é assim: IDHttp1.Get(‘seu link’, variavelStream).

Bacana, vi que funcionava assim, mas eu queria que fosse exibido o andamento do download, para os casos de arquivos maiores.

Tentei algumas formas utilizando diretamente o TIDHttp, mas não tinha conseguido obter sucesso.
Então continuei pesquisando e encontrei um post no stackoverflow um post com um exemplo de como resolver este problema.

Peguei este exemplo testei e funcionou. Fiz alguns pequenos ajustes e agora o exemplo funciona também em Lazarus.

Ficou interessado? Então vamos ao código!

Seguinte, para iniciar, vamos criar uma unit com o nome util.download.

Nesta unit vamos implementar uma classe que herda de TIDHttp e adicionar algumas funções que nos permita verificar o andamento do download.

Segue o código com comentários sobre as etapas:

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
{                                                                      }
{    TIdHTTPProgress - Extendend TIdHTTP to show progress download     }
{                                                                      }
{    Creted in https://stackoverflow.com/questions/28457925/how-to-download-a-file-with-progress-with-idhttp-via-https   }
{                                                                      }
{ Fixed and adapted to Lazarus and Delphi by Giovani Da Cruz           }
{                                                                      }
{ Please visit: https://showdelphi.com.br                              }
{----------------------------------------------------------------------}
unit util.download;
 
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;
 
{ Compatibilidade com lazarus }
{$IFDEF FPC}
OnWork := @HTTPWork;
OnWorkBegin := @HTTPWorkBegin;
OnWorkEnd := @HTTPWorkEnd;
{$ELSE}
OnWork := HTTPWork;
OnWorkBegin := HTTPWorkBegin;
OnWorkEnd := HTTPWorkEnd;
{$ENDIF}
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
{ Evento interno responsável por informar o progresso atual }
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.SetOnChange(const Value: TNotifyEvent);
begin
FOnChange := Value;
end;
 
procedure TIdHTTPProgress.SetProgress(const Value: Integer);
begin
FProgress := Value;
if Assigned(FOnChange) then
FOnChange(Self);
end;
 
end.

Note que o código fonte acima já está ajustado para poder ser utilizado tanto em Delphi quanto em Lazarus.

Show de bola! Agora que já temos a nossa nova classe, vamos precisar utiliza-la.
Para isso vamos ao exemplo de um botão de download em um formulário.

Vamos ao exemplo de como baixar monitorando o progresso!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{ Botão que efetua o download }
procedure TForm1.bDownloadClick(Sender: TObject);
var
IdHTTPProgress : TIdHTTPProgress;
begin
 
IdHTTPProgress := TIdHTTPProgress.Create(Self);
 
try
{$IFDEF FPC}
IdHTTPProgress.OnChange := @ProgressOnChange;
IdHTTPProgress.OnWorkEnd := @WorkEnd;
{$ELSE}
IdHTTPProgress.OnChange := ProgressOnChange;
IdHTTPProgress.OnWorkEnd := WorkEnd;
{$ENDIF}
 
IdHTTPProgress.DownloadFile(edURL.Text, edFile.Text + edArq.Text);
finally
FreeAndNil(IdHTTPProgress);
end;
end;

Mas só isso? Sim é realmente só isso, mas repare que no exemplo acima estou setando dois eventos para o objeto: “ProgressOnChange” e “WorkEnd”. Estes são os eventos que fazem a atualização da barra de progresso e que avisam quando o download foi concluído.

Então vamos aos códigos dos eventos:
Primeiro do evento para monitorar o progresso:

1
2
ProgressBar1.Position := TIdHTTPProgress(Sender).Progress;
Application.ProcessMessages;

Agora o evento que avisa quando o download foi concluído.

1
2
3
4
5
procedure TForm1.WorkEnd(ASender: TObject; AWorkMode: TWorkMode);
begin
ProgressBar1.Position := 100;
ShowMessage('Concluído!');
end;

Pronto, temos tudo para baixar arquivos com monitoramento do andamento do processo!

Para ajudar no entendimento, assista o vídeo abaixo que explica o código deste post.

Também deixamos a unit em um repositório no Github: https://github.com/infussolucoes/IDHttpProgress

Certo pessoal, espero que tenham gostado, lembrando que para dúvidas ou sugestões, utilizem os comentários.

Um abraço e até a próxima. Valeu!

  • Giovani Da Cruz
  • 2 comentários
  • 22 de setembro de 2019

2 respostas para “Como fazer Download de Arquivos com Progresso do andamento?”

  1. Mário Reis disse:

    Tentei repeti todos os passos.Tentei compilar dá erro!?
    Addicionei o IdComponent, continuo a não conseguir!?
    O que perdi

  2. Qual erro que você está tendo Mário?

Deixe um comentário

Ir ao topo

© 2024 Infus Soluções em Tecnologia - Todos os Direitos Reservados