Aqui na empresa estamos desenvolvendo um atualizador online, onde ele irá fazer o download e a execução da atualização para os clientes.
Como a nossa internet brasileira não é confiável, e ainda temos muitos clientes que utilizam internet discada, surgiu a necessidade de continuar os downloads de arquivos.
Após pesquisas, e a grande ajuda do Fábio Matsuda fui buscar no componente IdHTTP da Indy a solução.
procedure TForm1.Download(url, pathLocal : String;);
var
eFile : TFileStream;
IdHTTP : TIdHTTP;
begin
idHTTP := TIdHTTP.Create(nil);
if FileExists(pathLocal) then //Caso o arquivo já exista ele o abre, caso contrário cria um novo
eFile := TFileStream.Create(pathLocal,fmOpenReadWrite)
else
eFile := TFileStream.Create(pathLocal,fmCreate);
try
try
eFile.Seek(0,soFromEnd); //Colocando o ponteiro no final do arquivo
IdHTTP.Head(url); //Buscando informações do arquivo
if eFile.Position < IdHTTP.Response.ContentLength then //Somente se o arquivo já não foi totalmente baixado
begin
IdHTTP.Request.ContentRangeStart := eFile.Position; //Definindo onde deve inciar o download
IdHTTP.Request.ContentRangeEnd := IdHTTP.Response.ContentLength; //Verificando o tamanho do arquivo
if eFile.Position > 0 then
begin //É importante que o range seja definido com o tamanho inicial e o final
IdHTTP.Request.Range := Format('%d-%d',[eFile.Position,IdHTTP.Response.ContentLength]);
end;
IdHTTP.Get(url,eFile);
end;
except
ShowMessage('Conexão interrompida.');
end;
finally
eFile.Free;
IdHTTP.Disconnect;
IdHTTP.Free;
end;
end;
Este é um pequeno exemplo para se continuar downloads já iniciados, aos menos atenciosos url e pathLocal são paramentos que indicam o endereço do arquivo na internet e onde ele será salvo respectivamente.
Lembrando que é importante verificar o arquivo, seja por md5, hash ou crc32, para não haver problema caso este não seja atualizado.
Com o componene TIdHTTP é fácil colocar uma barra de progresso para o download, você já possui o tamanho total do arquivo
IdHTTP.Response.ContentLength
e o evento
OnWork
vai lhe informando quantos bytes já foram baixados pela variável
AWorkCount
IdHTTP.OnWork(ASender: TObject; AWorkMode: TWorkMode;
AWorkCount: Integer);
begin
Progress.Position := Trunc((AWorkCount/IdHTTP.Response.ContentLength)*100);
end;
Pronto, só lembrando que desenvolvi utilizando Indy 10 e Delphi 2007, não testei em versões anteriores.