使用Delphi和Indy通过Progress事件以编程方式从Internet下载文件

Sal*_*dor 14 delphi indy download delphi-7

我需要一种通过HTTP使用Delphi从Internet下载文件的方法,其中包括Progress事件,我正在寻找一种使用Indy组件的方法.

我使用的是Delphi 7.

ulr*_*chb 21

我用Indy 10编写了这个例子,只使用了一个HTTP GET,希望它也适用于Indy 9:

uses
  {...} IdHTTP, IdComponent;

type
  TFormMain = class(TForm)
    {...}
  private
    {...}
    procedure HttpWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
  end;
{...}

procedure TFormMain.Button1Click(Sender: TObject);
var
  Http: TIdHTTP;
  MS: TMemoryStream;
begin
  Http := TIdHTTP.Create(nil);
  try
    MS := TMemoryStream.Create;
    try
      Http.OnWork:= HttpWork;

      Http.Get('http://live.sysinternals.com/ADExplorer.exe', MS);
      MS.SaveToFile('C:\ADExplorer.exe');

    finally
      MS.Free;
    end;
  finally
    Http.Free;
  end;
end;

procedure TFormMain.HttpWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
var
  Http: TIdHTTP;
  ContentLength: Int64;
  Percent: Integer;
begin
  Http := TIdHTTP(ASender);
  ContentLength := Http.Response.ContentLength;

  if (Pos('chunked', LowerCase(Http.Response.TransferEncoding)) = 0) and
     (ContentLength > 0) then
  begin
    Percent := 100*AWorkCount div ContentLength;

    MemoOutput.Lines.Add(IntToStr(Percent));
  end;
end;
Run Code Online (Sandbox Code Playgroud)

  • 不要使用`Application.ProcessMessages()`.这将为所有待处理消息抽取消息队列,如果您不小心,可能会导致副作用和重新进入问题.最好使用`TForm.Update()`方法来处理只有挂起的绘制消息而不处理其他消息. (8认同)
  • Response.ContentLength值并不总是有效.特别是,在使用"分块"传输编码的HTTP 1.1回复中,不允许使用"Content-Length"标头.在分块传输期间,数据的总大小未提前知道,因为数据以多个块传输,并且每个块在内部具有其自己的大小. (2认同)
  • 并且不要忘记在OnWork事件上编写`Application.ProcessMessages();`! (2认同)