Скачивайте файл постепенно используя TIdHttp
Я хочу реализовать простой загрузчик http, используя TIdHttp (Indy10). Я нашел два вида примеров кода из Интернета. К сожалению, никто из них не удовлетворяет меня на 100%. Вот код, и я хочу несколько советов.
Вариант 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;
Код компактен и очень прост для понимания. Проблема в том, что он выделяет место на диске, когда начинается загрузка. Другая проблема заключается в том, что мы не можем напрямую показать ход загрузки в графическом интерфейсе, если код не выполняется в фоновом потоке (в качестве альтернативы мы можем связать событие HttpClient.OnWork).
Вариант 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;
Сначала мы запрашиваем размер файла с сервера, а затем загружаем содержимое файла по частям. Полученное содержимое файла будет сохранено на диск, когда оно будет получено полностью. Потенциальная проблема заключается в том, что мы должны отправить несколько запросов GET на сервер. Я не уверен, что некоторые серверы (например, megaupload) могут ограничивать количество запросов в течение определенного периода времени.
Мои ожидания
Загрузчик должен отправить только один GET-запрос на сервер.Дисковое пространство не должно выделяться при начале загрузки.Любые советы приветствуются.