Как скачать файлы, используя данные из tstring? Delphi и THttpGet - PullRequest
0 голосов
/ 26 января 2012

У меня есть два списка строк: name (содержит имена файлов), url (содержит URL-адреса файлов). Я хотел бы загрузить все необходимые файлы, используя THttpget в один цикл, с индикатором выполнения:

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

Работает, но загружает только один файл - сначала в списке строк. Как я могу это сделать? numberOfDownloads - количество элементов в имени списка строк.

Ответы [ 2 ]

2 голосов
/ 26 января 2012

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;
1 голос
/ 26 января 2012

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