-1

我有两个字符串列表:name(包含文件名)、url(包含文件 url)。我想在一个循环中使用 THttpget 下载所有必需的文件,并带有进度条:

for d:=0 to numberOfDownloads-1 do
begin
HTTPGet2.URL:=url[d];
HTTPGet2.FileName:=name[d];
HTTPGet2.GetFile;
end;

它可以工作,但它只下载一个文件 - 首先在字符串列表中。我怎样才能做到这一点?numberOfDownloads - 字符串列表名称中的项目数。

4

2 回答 2

2

HTTPGet 通过创建辅助线程并通过标准事件通知来异步下载文件。

因此,在您的情况下,当您遍历循环并获取要下载的第二个文件时,HTTPGet2 实例仍在忙于处理先前的下载。

克服这个问题的一个简单方法是创建一个 HTTPGet 实例数组......像这样......

 var HTTPGets: array of THttpGet;
   ...
 setlength(HTTPGets,numberOfDownloads);
 ...
 for d:=0 to numberOfDownloads-1 do
   begin
    HTTPGets[d]:=THttpGet.Create(...);
    HTTPGets[d].URL:=...;
     ...
    HTTPGets[d].GetFile;
   end;
 end.

并获得有关终结事件的通知,您需要创建自己的 OnDoneFile 并设置它...

   HTTPGets[d].OnDoneFile:=HTTPGetOnDone;
于 2012-01-26T19:18:12.557 回答
1

下面的近似代码摘自使用 Indy 组件的工作版本。您需要填补一些空白以使其编译,但它应该会给您这个想法。对于多个文件,要么像循环一样重复调用,要么使用文件名列表调用,并让下面的代码在内部循环......

type
  TDownloadResult = (DRSuccess, DRHostNotFound, DRFileNotFound, DRUserCancelled, DROther);

function TDownload.Download(const aSourceURL: String;
                            const aDestFileName: String;
                            const aShowProgress: Boolean;
                            out   aDownloadResult: TDownloadResult;
                            out   aErrm: String): boolean;
var
  Stream: TMemoryStream;
  IDAntiFreeze: TIDAntiFreeze;
begin
  Screen.Cursor := crHourGlass;
  aDownloadResult := DROther;
  aErrm :='Unexpected web error.';
  fShowProgress := aShowProgress;
  if fShowProgress then
    begin
      frmProgressBar := TfrmProgressBar.Create(Application.MainForm);
      frmProgressBar.SetMessage1'Downloading File...');
      frmProgressBar.Show;
    end;

  fIDHTTP := TIDHTTP.Create;
  fIDHTTP.HandleRedirects := TRUE;
  fIDHTTP.AllowCookies := FALSE;
  fIDHTTP.Request.UserAgent := 'Mozilla/4.0';
  fIDHTTP.Request.Connection := 'Keep-Alive';
  fIDHTTP.Request.ProxyConnection := 'Keep-Alive';
  fIDHTTP.Request.CacheControl := 'no-cache';
  fIDHTTP.OnWork := IdHTTP1Work;
  fIDHTTP.OnWorkBegin := IdHTTP1WorkBegin;
  IDAntiFreeze := TIDAntiFreeze.Create;

  Stream := TMemoryStream.Create;
  try
    try
      fIDHTTP.Get(aSourceURL, Stream);
      if FileExists(aDestFileName) then
        DeleteFile(PWideChar(aDestFileName));
      Stream.SaveToFile(aDestFileName);
      Result := TRUE;
      aDownloadResult :=drSuccess;
    except
      On E: Exception do
        begin
          Result := FALSE;
          aErrm := E.Message + ' (' + IntToStr(fIDHTTP.ResponseCode) + ')';
          if fShowProgress AND fShowProgress AND frmProgressBar.Cancelled then
            aDownloadResult := DRUserCancelled
          else if (fIDHTTP.ResponseCode = 404) OR (fIDHTTP.ResponseCode = 302) then
            aDownloadResult := DRFileNotFound
          else if (FIDHTTP.ResponseCode = -1) then
            aDownloadResult := DRHostNotFound
          else
            aDownloadResult := DROther;
        end;
    end;
  finally
    Screen.Cursor := crDefault;
    Stream.Free;
    IDAntiFreeze.Free;
    fIDHTTP.Free;
    if fShowProgress then
      frmProgressBar.Free;
  end;
end;  { Download }


procedure TDownload.IdHTTP1Work(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
begin
  if fShowProgress AND frmProgressBar.Cancelled then
     raise EUserCancelled.Create('');
  if fShowProgress AND (fMaxWork > 0) then
    frmProgressBar.SetPosition(AWorkCount, GetMsg(MSG_PERCENT_COMPLETE, IntToStr( Round(AWorkCount/fMaxWork * 100)) + '%'));
end; { IdHTTP1Work }

procedure TDownload.IdHTTP1WorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64);
begin
  fMaxWork := AWorkCountMax;
  if fShowProgress then
    frmProgressBar.SetMinMax(0, fMaxWork);
end; { IdHTTP1WorkBegin }

样品用途:

procedure TForm1.Button1Click(Sender: TObject);
var
  Download: TDownload;
  Errm: String;
  DownloadResult: TDownloadResult;
begin
  Download := TDownload.Create;
  if NOT TDownload.Download( 'http://www.URL.com/filename.ext',
                             'c:\junk\au.mpg', TRUE, DownloadResult, Errm) then
    begin
      case DownloadResult of
         DRFileNotFound: ShowMessage ('File not found!!' + #13 + Errm);
         DRUserCancelled: ShowMessage ('Cancelled!');
         DrHostNotFound: ShowMessage ('Are you on line?');
         DrOther: ShowMessage ('Other: ' + Errm);
      else
        ShowMessage('huh?');
      end
    end
  else
    ShowMessage ('Download succeeded!');
end;
于 2012-01-26T19:10:59.387 回答