Here is how to upload a folder. Source.
{
Upload the LocalDir to an FTP server, in the RemoteDir.
If RemoteDir does not exist it is created.
All files and subfolders of LocalDir will be uploaded.
FTP parameters (username, password, server) must be already provided.
The caller must connnect to the server before calling UploadFolderToFtp and disconnect after that }
procedure UploadFolderToFtp(FTP: TIdFTP; LocalDir, RemoteDir, Filter: string);
procedure GoToSubDir(SubDir: string);
VAR
details, nodetails: TStringList;
k: Integer;
begin
details := TStringList.Create; //get folder contents from ftp. one with details, one without
nodetails := TStringList.Create;
TRY
FTP.List(details, '', True);
FTP.List(nodetails, '', False);
//we only want to have directories in the list (without '.' and '..')
for k := details.Count - 1 downto 0 do
if details.Strings[k] <> '' then
if (PosInsensitive('dir', details.Strings[k]) < 1)
OR (nodetails.Strings[k] = '.')
OR (nodetails.Strings[k] = '..') then
begin
details.Delete(k);
nodetails.Delete(k);
end;
//if our directory does not exists on the server, create it
if nodetails.IndexOf(SubDir) = -1
then FTP.MakeDir(SubDir);
FINALLY
FreeAndNil(Details);
FreeAndNil(nodetails);
END;
FTP.ChangeDir(SubDir); //change into next directory on server
end;
procedure uploadDir(dir: string);
VAR
s: string;
List: TStringList;
begin
List:= ListDirectoriesOf(dir, FALSE, FALSE); //iterate through subdirectories
for s in List DO
begin
GoToSubDir(s);
uploadDir(dir + s + '\'); //and also locally go into the next subfolder
FTP.ChangeDirUp; //we have to go one directory up after leaving the recursion
end;
FreeAndNil(List);
List:= ListFilesOf(dir, Filter, FALSE, FALSE); //iterate through files
for s in List DO
begin
Assert(s > '', 'File name should not be empty!');
FTP.Put(dir + s, s); //if it's only a file, upload it to the current directory;
end;
FreeAndNil(List);
end;
VAR
subdir, dir: string;
begin
//does not matter if RemoteDir is like 'dir\dir' or 'dir/dir'
dir := StringReplace(RemoteDir, '\', '/', [rfReplaceAll]);
if dir <> '' then
begin
if dir[1] = '/' then Delete(dir, 1, 1); //remove first '/' if there's one
if dir[Length(dir)] <> '/' then dir := dir + '/'; // add a '/' at the end
//loop through our remote-directories
WHILE Pos('/', dir) > 0 DO
begin
SubDir:= system.Copy(dir, 1, Pos('/', dir) - 1);
//if our directory does not exists on the server, we create it
GoToSubDir(SubDir);
//remove first directory from path ('your/directory/subdir/' --> 'directory/subdir/')
Delete(dir, 1, Pos('/', dir));
end;
end;
dir := LocalDir;
if dir[Length(dir)] <> '\'
then dir := dir + '\';
uploadDir(dir); // begin the upload
end;
procedure TfrmFTP.Button1Click(Sender: TObject);
begin
if Connect {Set parameters for FTP and connect to server }
then UploadFolderToFtp(ftp, 'c:\test\', RemoteDir, '*.*')
else SwMessage('Cannot connect to '+ FTP.ServerHOST);
Disconnect;
end;
--
ListDirectoriesOf & ListFilesOf is a function that returns the subdirectories/files of the specified folder (it returns non-full path)