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文件,续传后后可以解压,但是里面老是丢失一部分内容

解决方案 »

  1.   

       原来顺序是这样的,但是结果是只能下载从断点处到最后的文件流 
        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); //开始下载 
      

  2.   

    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 的部分
      

  3.   

    用工具先把rar文件下载,然后与你自已写的代码下载的rar文件进行对比.或者调试一下,看看哪里出了问题.
      

  4.   

    发给例子
    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;
      

  5.   

    //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;