idhttp续传问题

小时候的天空 2009-05-04 05:03:51
procedure Tf_rardown.HttpDownLoad(aURL, aFile: string; bResume: Boolean);
var
mid_path :string;
Size:integer;
fs,ms: TMemoryStream;
tStream,tempStream: TFileStream;

begin //Http方式下载

IDHttp1.HandleRedirects := True;
IDHttp1.ReadTimeout := 60000;
mid_path:= ExtractFilepath(Application.ExeName)+'download\'+'mid.rar';

if FileExists(aFile) then //如果文件已经存在
begin
tStream := TFileStream.Create(aFile, fmOpenReadWrite);
end
else
begin
tStream := TFileStream.Create(aFile, fmCreate);

end;


try
if bResume then //续传方式
begin

tempStream:=TFileStream.Create(mid_path, fmCreate);

// tempStream.Seek(0,soFromEnd);

// tempStream.CopyFrom(tStream,tStream.size);
//tempStream.Free;
IdHTTP1.Head(aURL);
IdHTTP1.Request.ContentRangeStart := tStream.Size -1;
tStream.Position := tStream.Size - 1 ; //移动到最后继续下载


IdHTTP1.Request.ContentRangeEnd := IdHTTP1.Response.ContentLength ;
pro_num := tStream.Size ;

IdHTTP1.Get(aURL, tStream); //开始下载

// tStream.Free;

// tStream:= TFileStream.Create(aFile, fmOpenWrite);
// tempStream:= TFileStream.Create(mid_path,fmOpenRead);
// tStream.Seek(0,soFromEnd);
// tStream.CopyFrom(tempStream,tempStream.Size);
//Size:=tempStream.Size+SizeOf(Size);
//tStream.WriteBuffer(Size,SizeOf(Size));
//tempStream.Free;

end
else //覆盖或新建方式
begin
IdHTTP1.Request.ContentRangeStart := 0;
IdHTTP1.Get(aURL, tStream); //开始下载

end;
//showmessage('下载失败!');
finally
tStream.Free;
end;
end;

这是网上找的,下载一个rar文件,续传后后可以解压,但是里面老是丢失一部分内容
...全文
231 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
singlexinglove 2010-06-23
  • 打赏
  • 举报
回复
//IdHTTP1.Request.ContentRangeEnd := IdHTTP1.Response.ContentLength;
这句注释掉
如下:
var
tStream: TFileStream;
begin //Http方式下载
if FileExists(aFile) then //如果文件已经存在
tStream := TFileStream.Create(aFile, fmOpenWrite)
else
tStream := TFileStream.Create(aFile, fmCreate);
try
if bResume then //续传方式
begin
IdHTTP1.Request.ContentRangeStart := tStream.Size - 1;
tStream.Position := tStream.Size - 1; //移动到最后继续下载
IdHTTP1.Head(aURL);
// IdHTTP1.Request.ContentRangeEnd := IdHTTP1.Response.ContentLength;--这句去掉
end
else //覆盖或新建方式
begin
IdHTTP1.Request.ContentRangeStart := 0;
end;

try
IdHTTP1.Get(aURL, tStream); //开始下载
finally
Result := True;
tStream.Free;
end;
except
Result := False;
end;
cp0313 2009-11-06
  • 打赏
  • 举报
回复
发给例子


function Download(var host1, file1: string): Boolean;
var
url1: string;
buf1: Tbuf_byte;
rec1: longint;
f1: file;
cmd1: string; //这一行的内容
reclen1, real_reclen1: longint; //服务器返回的长度;实际已经收到的长度
value1: string; //标志们的值
total_len1: longint; //数据总长
begin
try
//self.filename1:='c:\temp1.dat';
assignfile(f1, file1);
Form_Update.can_rec1 := false;
Form_update.stop1 := false;
if FileExists(file1) = true then
begin
reset(f1, 1);
pos1 := filesize(f1);
end
else
begin
rewrite(f1, 1);
pos1 := 0;
end;
seek(f1, pos1);
Form_Update.ClientSocket1.Active := false;
Form_Update.ClientSocket1.Host := get_host1(host1);
Form_Update.ClientSocket1.Port := 80;
url1 := '';
Form_Update.serfilename := get_file1(host1);
Form_Update.serhost1 :=get_host1(host1);
//取得文件长度以确定什么时候结束接收[通过"head"请求得到]
Form_Update.ClientSocket1.Active := false;
Form_Update.ClientSocket1.Active := true;
url1 := '';
url1 := url1 + 'HEAD /' + Form_Update.serfilename + ' HTTP/1.1' + #13#10;
//不使用缓存,我附加的
//与以前的服务器兼容
url1 := url1 + 'Pragma: no-cache' + #13#10;
//新的
url1 := url1 + 'Cache-Control: no-cache' + #13#10;
//不使用缓存,我附加的_end;
url1 := url1 + 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)' + #13#10;
//下面这句必须要有
//url1:=url1+'Host: clq.51.net'+#13#10;
url1 := url1 + 'Host: ' + Form_Update.serhost1 + #13#10;
url1 := url1 + #13#10;
Form_Update.ClientSocket1.Socket.SendText(url1);
while Form_Update.ClientSocket1.Active = true do
begin
if Form_Update.stop1 = true then break;
cmd1 := socket_rec_line1(Form_Update.ClientSocket1.Socket, 60 * 1000);
//计算文件的长度
if pos(lowercase('Content-Length: '), lowercase(cmd1)) = 1 then
begin
value1 := copy(cmd1, length('Content-Length: ') + 1, length(cmd1));
total_len1 := strtoint(trim(value1));
end;
//计算文件的长度_end;
if cmd1 = #13#10 then break;
end;
//取得文件长度以确定什么时候结束接收_end;
//发送get请求,以得到实际的文件数据
Form_Update.clientsocket1.Active := false;
Form_Update.clientsocket1.Active := true;
url1 := '';
//url1:=url1+'GET http://clq.51.net/textfile.zip HTTP/1.1'+#13#10;
//url1:=url1+'GET /textfile.zip HTTP/1.1'+#13#10;
url1 := url1 + 'GET /' + Form_Update.serfilename + ' HTTP/1.1' + #13#10;
url1 := url1 + 'Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*' + #13#10;
//应该可以不要url1:=url1+'Accept-Language: zh-cn'+#13#10;
//应该可以不要url1:=url1+'Accept-Encoding: gzip, deflate'+#13#10;
//不使用缓存,我附加的
//与以前的服务器兼容
//url1:=url1+'Pragma: no-cache'+#13#10;
//新的
//url1:=url1+'Cache-Control: no-cache'+#13#10;
//不使用缓存,我附加的_end;
url1 := url1 + 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)' + #13#10;
//接受数据的范围,可选
//url1:=url1+'RANGE: bytes=533200-'+#13#10;
url1 := url1 + 'RANGE: bytes=' + inttostr(pos1) + '-' + #13#10;
//下面这句必须要有
//url1:=url1+'Host: clq.51.net'+#13#10;
url1 := url1 + 'Host: ' + Form_Update.serhost1 + #13#10;
//应该可以不要
//url1:=url1+'Connection: Keep-Alive'+#13#10;
url1 := url1 + #13#10;
Form_Update.ClientSocket1.Socket.SendText(url1);
while Form_Update.ClientSocket1.Active = true do
begin
if Form_Update.stop1 = true then break;
cmd1 := socket_rec_line1(Form_Update.ClientSocket1.Socket, 60 * 1000);
//是否可接收
if pos(lowercase('Content-Range:'), lowercase(cmd1)) = 1 then
begin
Form_Update.can_rec1 := true;
end;
//是否可接收_end;
//计算要接收的长度
if pos(lowercase('Content-Length: '), lowercase(cmd1)) = 1 then
begin
value1 := copy(cmd1, length('Content-Length: ') + 1, length(cmd1));
reclen1 := strtoint(trim(value1));
end;
//计算要接收的长度_end;
//头信息收完了
if cmd1 = #13#10 then break;
end;
real_reclen1 := 0;
while Form_Update.ClientSocket1.Active = true do
begin
if Form_Update.stop1 = true then break;
//不能接收则退出
if Form_Update.can_rec1 = false then break;
//如果文件当前的长度大于服务器标识的长度,则是出错了,不要写入文件中
if filesize(f1) >= total_len1 then
begin
//showmessage('文件已经下载完毕了!');
result := true;

break;
end;
zeromemory(@buf1, sizeof(buf1));
rec1 := Form_Update.ClientSocket1.Socket.ReceiveBuf(buf1, sizeof(buf1));
//如果实际收到的长度大于服务器标识的长度,则是出错了,不要写入文件中
if real_reclen1 >= reclen1 then
begin
//showmessage('文件已经下载完毕了!');
result := true;

break;
end;
//如果当前的长度大于服务器标识的长度,则是出错了,不要写入文件中
if pos1 = reclen1 then
begin
//showmessage('文件已经下载完毕了!');
result := true;

break;
end;
blockwrite(f1, buf1, rec1);
real_reclen1 := real_reclen1 + rec1;
// Sleep(1);
//显示下载进度
Form_Update.Label4.Caption := '共 ' + FormatFloat('#,##', reclen1) + ' 字节,已下载 ' + FormatFloat('#,##', real_reclen1) + ' 字节';
Form_Update.Gauge_process.MaxValue := reclen1;
Form_Update.Gauge_process.Progress := real_reclen1;
application.ProcessMessages;
end;
closefile(f1);
//发送get请求,以得到实际的文件数据_end;
Form_Update.ClientSocket1.Active := false;
except
closefile(f1);
//showmessage('连接失败...');
result := false;

end;
end;
beiguofengguang 2009-11-05
  • 打赏
  • 举报
回复
我也遇到相同的问题,奇怪了。
续下载的时候老是只下再上次没下载完的,导致文件不完整。也不知道问题出在哪里了
sxy_9761 2009-06-04
  • 打赏
  • 举报
回复
用工具先把rar文件下载,然后与你自已写的代码下载的rar文件进行对比.或者调试一下,看看哪里出了问题.
小时候的天空 2009-06-04
  • 打赏
  • 举报
回复
看来还得自己慢慢研究
小时候的天空 2009-05-05
  • 打赏
  • 举报
回复
IdHTTP1.Head(aURL);
放到
IdHTTP1.Request.ContentRangeStart := tStream.Size -1;
上面文件大小没问题,但是解压后里面文件不全

如果是这样
IdHTTP1.Request.ContentRangeStart := tStream.Size - 1;
tStream.Position := tStream.Size - 1; //移动到最后继续下载
IdHTTP1.Head(aURL);
IdHTTP1.Request.ContentRangeEnd := IdHTTP1.Response.ContentLength;
文件是ContentRangeStart 到 ContentRangeEnd 的部分
lhy 2009-05-05
  • 打赏
  • 举报
回复
文件大小有没有问题?
cnhxjtoa 2009-05-04
  • 打赏
  • 举报
回复
gz
小时候的天空 2009-05-04
  • 打赏
  • 举报
回复
各位大哥大姐帮帮忙了
小时候的天空 2009-05-04
  • 打赏
  • 举报
回复
原来顺序是这样的,但是结果是只能下载从断点处到最后的文件流
IdHTTP1.Request.ContentRangeStart := tStream.Size -1;
tStream.Position := tStream.Size - 1 ; //移动到最后继续下载


IdHTTP1.Request.ContentRangeEnd := IdHTTP1.Response.ContentLength ;
pro_num := tStream.Size ;
IdHTTP1.Head(aURL);
IdHTTP1.Get(aURL, tStream); //开始下载

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧