Descarga el archivo progresivamente usando TIdHttp
Quiero implementar un descargador de http simple usando TIdHttp (Indy10). Encontré dos tipos de ejemplos de código de internet. Lamentablemente ninguno de ellos me satisface al 100%. Aquí está el código y quiero un consejo.
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;
El código es compacto y muy fácil de entender. El problema es que asigna espacio en disco cuando comienza la descarga. Otro problema es que no podemos mostrar el progreso de la descarga directamente en la GUI, a menos que el código se ejecute en un subproceso en segundo plano (como alternativa, podemos vincular el 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;
Primero, consultamos el tamaño del archivo desde el servidor y luego descargamos el contenido del archivo en partes. El contenido del archivo recuperado se guardará en el disco cuando se reciba por completo. El problema potencial es que tenemos que enviar varias solicitudes GET al servidor. No estoy seguro de si algunos servidores (como megaupload) pueden limitar el número de solicitudes dentro de un período de tiempo determinado.
Mis expectativas
El descargador debe enviar solo una solicitud GET al servidor.El espacio en disco no debe asignarse cuando comienza la descarga.Cualquier consejo es apreciado.