【发布时间】:2012-11-18 10:16:28
【问题描述】:
我想使用 TIdHttp (Indy10) 实现一个简单的 http 下载器。我从互联网上找到了两种代码示例。不幸的是,他们都没有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;
代码紧凑且非常容易理解。问题是它在下载开始时分配磁盘空间。另一个问题是我们不能直接在 GUI 中显示下载进度,除非代码在后台线程中执行(或者我们可以绑定 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 请求。
- 下载开始时不得分配磁盘空间。
感谢任何提示。
【问题讨论】:
-
如果你想要缓存
TFileStream,请查看 David 的贡献:Buffered files (for faster disk access)。
标签: delphi http download indy idhttp