Я хочу реализовать простой 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.
- Дисковое пространство не должно выделяться при загрузке.
Любые намеки приветствуются.