Voglio implementare un semplice downloader HTTP usando TIdHttp (Indy10). Ho trovato due tipi di esempi di codice da internet. Sfortunatamente nessuno di loro mi soddisfa al 100%. Ecco il codice e voglio qualche consiglio.Scarica il file progressivamente usando TIdHttp
Variante 1
var
Buffer: TFileStream;
HttpClient: TIdHttp;
begin
Buffer := TFileStream.Create('somefile.exe', fmCreate or fmShareDenyWrite);
try
HttpClient := TIdHttp.Create(nil);
try
HttpClient.Get('http://somewhere.com/somefile.exe', Buffer); // wait until it is done
finally
HttpClient.Free;
end;
finally
Buffer.Free;
end;
end;
Il codice è compatto e molto facile da capire. Il problema è che alloca lo spazio su disco all'avvio del download. Un altro problema è che non possiamo mostrare direttamente l'avanzamento del download nella GUI, a meno che il codice non venga eseguito in un thread in background (in alternativa possiamo associare l'evento HttpClient.OnWork).
Variante 2:
const
RECV_BUFFER_SIZE = 32768;
var
HttpClient: TIdHttp;
FileSize: Int64;
Buffer: TMemoryStream;
begin
HttpClient := TIdHttp.Create(nil);
try
HttpClient.Head('http://somewhere.com/somefile.exe');
FileSize := HttpClient.Response.ContentLength;
Buffer := TMemoryStream.Create;
try
while Buffer.Size < FileSize do
begin
HttpClient.Request.ContentRangeStart := Buffer.Size;
if Buffer.Size + RECV_BUFFER_SIZE < FileSize then
HttpClient.Request.ContentRangeEnd := Buffer.Size + RECV_BUFFER_SIZE - 1
else
HttpClient.Request.ContentRangeEnd := FileSize;
HttpClient.Get(HttpClient.URL.URI, Buffer); // wait until it is done
Buffer.SaveToFile('somefile.exe');
end;
finally
Buffer.Free;
end;
finally
HttpClient.Free;
end;
end;
In primo luogo abbiamo interrogare la dimensione del file dal server e poi scaricare il contenuto dei file in pezzi. I contenuti dei file recuperati verranno salvati sul disco quando vengono ricevuti completamente. Il potenziale problema è che dobbiamo inviare più richieste GET al server. Non sono sicuro che alcuni server (come megaupload) potrebbero limitare il numero di richieste entro un determinato periodo di tempo.
Le mie aspettative
- Il downloader devono inviare un solo GET-richiesta al server.
- Lo spazio su disco non deve essere allocato all'avvio del download.
Eventuali suggerimenti sono apprezzati.
Se si desidera un caching 'TFileStream', guarda Il contributo di David qui: [File bufferizzati (per un accesso più veloce al disco)] (http://stackoverflow.com/a/5639712/576719). –