* * *

Author Topic: Synapse ftp list recursively  (Read 604 times)

Hellios

  • Newbie
  • Posts: 2
Synapse ftp list recursively
« on: June 30, 2017, 03:55:52 am »
Hey everyone.

I'm writing a small ftp client for fun, using synapse (TFTPSend) and i wanna make a procedure to list everything in its folder and every subfolder.
Trying to use the same method as TSearchRec i came up with something like this:

Code: Pascal  [Select]
  1. var
  2.   FTP: TFTPSend;
  3.  
  4. procedure TFtpSync.ListAllFiles(const aDir: string);
  5. var
  6.   i: integer;
  7.   s: string;
  8. begin
  9.   FTP.List(aDir, false);
  10.   for i := 0 to FTP.FtpList.Count - 1 do begin
  11.     s := aDir + '/' + FTP.FtpList[i].FileName;
  12.     WriteLn(s);
  13.     if FTP.FtpList[i].Directory then begin
  14.       // FTP.ChangeWorkingDir(s);
  15.       ListAllFiles(s);
  16.     end;
  17.   end;
  18. end;

..but it's not working as supposed to. I'd really appreciate it if someone could give me a tip or a small example.

Thank you in advance~!

Remy Lebeau

  • Sr. Member
  • ****
  • Posts: 335
    • Lebeau Software
Re: Synapse ftp list recursively
« Reply #1 on: July 01, 2017, 12:11:38 am »
Trying to use the same method as TSearchRec i came up with something like this:

..but it's not working as supposed to. I'd really appreciate it if someone could give me a tip or a small example.

Think of what happens when a recursive call to ListAllFiles() modifies FTP.FtpList while the previous call is still iterating it.  You don't have that problem with a recursive FindFirst/Next() loop because FindFirst() opens a new search handle each time it is called.

Try something more like this:

Code: Pascal  [Select]
  1. procedure TFtpSync.ListAllFiles(const aDir: string);
  2. var
  3.   i: integer;
  4.   s: string;
  5.   dirs: TStringList;
  6. begin
  7.   dirs := nil;
  8.   try
  9.     FTP.List(aDir, false);
  10.     for i := 0 to FTP.FtpList.Count - 1 do begin
  11.       s := aDir + '/' + FTP.FtpList[i].FileName;
  12.       WriteLn(s);
  13.       if FTP.FtpList[i].Directory then begin
  14.         if dirs = nil then
  15.           dirs := TStringList.Create;
  16.         dirs.Add(s);
  17.       end;
  18.     end;
  19.     if dirs <> nil then begin
  20.       for i := 0 to dirs.Count - 1 do begin
  21.         FTP.ChangeWorkingDir(dirs[i]);
  22.         ListAllFiles(dirs[i]);
  23.       end;
  24.     end;
  25.   finally
  26.     dirs.Free;
  27.   end;
  28. end;

Or:

Code: Pascal  [Select]
  1. procedure TFtpSync.ListAllFiles(const aDir: string);
  2. var
  3.   i: integer;
  4.   s: string;
  5.   dirs: TStringList;
  6. begin
  7.   dirs := nil;
  8.   try
  9.     FTP.List(aDir, false);
  10.     for i := 0 to FTP.FtpList.Count - 1 do begin
  11.       s := FTP.FtpList[i].FileName;
  12.       WriteLn(aDir + '/' + s);
  13.       if FTP.FtpList[i].Directory then begin
  14.         if dirs = nil then
  15.           dirs := TStringList.Create;
  16.         dirs.Add(s);
  17.       end;
  18.     end;
  19.     if dirs <> nil then begin
  20.       for i := 0 to dirs.Count - 1 do begin
  21.         FTP.ChangeWorkingDir(dirs[i]);
  22.         ListAllFiles(dirs[i]);
  23.         FTP.ChangeToParentDir;
  24.       end;
  25.     end;
  26.   finally
  27.     dirs.Free;
  28.   end;
  29. end;
« Last Edit: July 01, 2017, 12:14:10 am by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) open source project - Admin, Developer

Hellios

  • Newbie
  • Posts: 2
Re: Synapse ftp list recursively
« Reply #2 on: July 01, 2017, 01:54:50 am »
Think of what happens when a recursive call to ListAllFiles() modifies FTP.FtpList while the previous call is still iterating it.  You don't have that problem with a recursive FindFirst/Next() loop because FindFirst() opens a new search handle each time it is called.

Woah yeah, you're absolutely right! I failed to think about that.

Thank you so much buddy for taking your time to help me out. I really spent few hours trying to find a solution about it.  ::)

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus