Brian Frost
Brian Frost

Reputation: 13454

How to download a folder of files from a web server using Delphi

I've checked out the usefule link how to download a file from internet using Delphi and my question related but I would appreciate a pointer to get started. I need to be able to copy all files in a web server folder down to a local folder. I wont know how many files there are, or indeed whether there is an internet connection. Are there component(s) that would help me please? Or can I use Windows API? Thanks Brian

Upvotes: 2

Views: 4738

Answers (4)

Jeroen Wiert Pluimers
Jeroen Wiert Pluimers

Reputation: 24483

I'd start with this answer and in stead of putting the output result in a string, write the buffer to a TFileStream.

WinInet is really nice, as it respects the proxy settings the user set on Windows (so you don't have to put a lot of work into how to make that configurable with Indy).

Edit:

I refactored that answer a bit to download binary files.
Since it uses WinInet you can use it for both ftp and http download (yes, I checked that it did).
You can extend this to use FtpFindFirstFile/InternetFindNextFile and read a whole bunch of files.

unit DownloadBinaryFileUnit;

interface

uses
  Classes,
  WinInet;

type
  TWinInet = class
  strict protected
    class procedure ReadBinaryFileResponse(const UrlHandle: HINTERNET; const LocalFileName: string); static;
    class procedure ReadResponse(const UrlHandle: HINTERNET; const ContentStream: TStream);
  public
    class procedure DownloadBinaryFile(const UserAgent, Url, LocalFileName: string); overload; static;
  end;


implementation

uses
  SysUtils,
  Variants,
  Windows,
  IOUtils;

class procedure TWinInet.DownloadBinaryFile(const UserAgent, Url, LocalFileName: string);
var
  InternetHandle: HINTERNET;
  UrlHandle: HINTERNET;
begin
  InternetHandle := InternetOpen(PChar(UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  try
    UrlHandle := InternetOpenUrl(InternetHandle, PChar(Url), nil, 0, 0, 0);
    try
      ReadBinaryFileResponse(UrlHandle, LocalFileName);
    finally
      InternetCloseHandle(UrlHandle);
    end;
  finally
    InternetCloseHandle(InternetHandle);
  end;
end;

class procedure TWinInet.ReadBinaryFileResponse(const UrlHandle: HINTERNET; const LocalFileName: string);
var
  ContentStream: TFileStream;
begin
  ContentStream := TFile.Create(LocalFileName);
  try
    ReadResponse(UrlHandle, ContentStream);
  finally
    ContentStream.Free;
  end;
end;

class procedure TWinInet.ReadResponse(const UrlHandle: HINTERNET; const ContentStream: TStream);
var
  Buffer: array[0..1023] of Byte;
  BytesRead: Cardinal;
begin
  repeat
    InternetReadFile(UrlHandle, @Buffer, SizeOf(Buffer), BytesRead);
    ContentStream.Write(Buffer, BytesRead);
  until BytesRead = 0;
end;

end.

--jeroen

Upvotes: 2

mjn
mjn

Reputation: 36654

If the HTTP server supports WebDAV, you can simply map a network drive and use file system commands to iterate the server side files.

If your application has no permissions to create network drives, one of the existing WebDAV client implementations for Delphi can be used instead.

Upvotes: 1

Remy Lebeau
Remy Lebeau

Reputation: 596216

If, and only if, the web server is configured to allow Directory Browsing (most servers do not), then you can request the URL of the folder and the web server will send back an HTML file containing the directory listing. You would then have to parse the HTML to determine the individual filenames, and then request their URLs one at a time.

If Directory Browsing is disabled, then there is no way to do what you are asking for without knowing the filenames ahead of time. Using FTP is a better choice, if available.

Upvotes: 3

Stijn Sanders
Stijn Sanders

Reputation: 36840

Since HTTP doesn't actually handle a concept as a folder of files, you should check if FTP is available on the server.

Still, if you're sure you're stuck to HTTP, you'll first have to find a way to collect a list of (full) URL's for all the files, and download them one by one using one of the techniques.

(You could then try to download more than one simultaneously, but ample experience teaches that bandwith is just that: bandwidth, and downloading a number of files one by one or all together takes about just as long.)

Upvotes: 0

Related Questions