开发者

Downloading a file in Delphi

开发者 https://www.devze.com 2023-01-11 19:27 出处:网络
A google search shows a few examples on how to download a file in Delphi but most are buggy and half of the time don\'t work in my experience.

A google search shows a few examples on how to download a file in Delphi but most are buggy and half of the time don't work in my experience.

I'm looking for a simple robust solution which will let me download a single exe (for updating my app) and will hold t开发者_如何学JAVAhe execution of the current update thread until the download is done or errors out. The process is already threaded so the download code should hold execution until it's done (hopefully).

Here's two implementations, both seem very complicated

1. http://www.scalabium.com/faq/dct0116.htm

2. http://delphi.about.com/od/internetintranet/a/get_file_net.htm


Why not make use of Indy? If you use the TIdHTTP component, it's simple:

procedure TMyForm.DownloadFile;    
var
  IdHTTP1: TIdHTTP;
  Stream: TMemoryStream;
  Url, FileName: String;
begin    
  Url := 'http://www.rejbrand.se';
  Filename := 'download.htm';

  IdHTTP1 := TIdHTTP.Create(Self);
  Stream := TMemoryStream.Create;
  try
    IdHTTP1.Get(Url, Stream);
    Stream.SaveToFile(FileName);
  finally
    Stream.Free;
    IdHTTP1.Free;
  end;
end;

You can even add a progress bar by using the OnWork and OnWorkBegin events:

procedure TMyForm.IdHTTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode;AWorkCountMax: Int64);
begin
  ProgressBar.Max := AWorkCountMax;
  ProgressBar.Position := 0;
end;

procedure TMyForm.IdHTTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
begin
  ProgressBar.Position := AWorkCount;
end;

procedure TMyForm.DownloadFile;    
var
  IdHTTP1: TIdHTTP;
  Stream: TMemoryStream;
  Url, FileName: String;
begin    
  Url := 'http://www.rejbrand.se';
  Filename := 'download.htm';

  IdHTTP1 := TIdHTTP.Create(Self);
  Stream := TMemoryStream.Create;
  try
    IdHTTP1.OnWorkBegin := IdHTTPWorkBegin;
    IdHTTP1.OnWork := IdHTTPWork;
    IdHTTP1.Get(Url, Stream);
    Stream.SaveToFile(FileName);
  finally
    Stream.Free;
    IdHTTP1.Free;
  end;
end;

I'm not sure if these events fire in the context of the main thread, so any updates done to VCL components may have to be done using the TIdNotify component to avoid threading issues. Maybe someone else can check that.


The second approach is the standard way of using Internet resources using WinINet, a part of Windows API. I have used it a lot, and it has always worked well. The first approach I have never tried. (Neither is "very complicated". There will always be a few additional steps when using the Windows API.)

If you want a very simple method, you could simply call UrlMon.URLDownloadToFile. You will not get any fine control (at all!) about the download, but it is very simple.

Example:

URLDownloadToFile(nil,
                  'http://www.rejbrand.se',
                  PChar(ExtractFilePath(Application.ExeName) + 'download.htm'),
                  0,
                  nil);


For people that has later version of delphi, you can use this:

var
  http : TNetHTTPClient;
  url : string;
  stream: TMemoryStream;
begin
  http := TNetHTTPClient.Create(nil);
  stream := TMemoryStream.Create;
  try
    url := YOUR_URL_TO_DOWNLOAD;
    http.Get(url, stream);
    stream.SaveToFile('D:\Temporary\1.zip');
  finally
    stream.Free;
    http.Free;
  end;
end;


Using URLMon.

errcode := URLMon.URLDownloadToFile(nil,
                      PChar('http://www.vbforums.com/showthread.php?345726-DELPHI-Download-Files'),
PChar( 'a:\download.htm'),
      0,
      nil);
if errcode > 0 then
      showmessage('Error while downloading: ' + inttostr(errcode));
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号