Synapse ftp list recursively lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- Hellios · 2017-06-30 01:55 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  FTP: TFTPSend; procedure TFtpSync.ListAllFiles(const aDir: string);var  i: integer;  s: string;begin  FTP.List(aDir, false);  for i := 0 to FTP.FtpList.Count - 1 do begin    s := aDir + '/' + FTP.FtpList[i].FileName;    WriteLn(s);    if FTP.FtpList[i].Directory then begin      // FTP.ChangeWorkingDir(s);      ListAllFiles(s);    end;  end;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 · 2017-06-30 22:11 Quote from: Hellios on June 30, 2017, 03:55:52 amTrying 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TFtpSync.ListAllFiles(const aDir: string);var  i: integer;  s: string;  dirs: TStringList;begin  dirs := nil;  try    FTP.List(aDir, false);    for i := 0 to FTP.FtpList.Count - 1 do begin      s := aDir + '/' + FTP.FtpList[i].FileName;      WriteLn(s);      if FTP.FtpList[i].Directory then begin        if dirs = nil then        dirs := TStringList.Create;        dirs.Add(s);      end;    end;    if dirs <> nil then begin      for i := 0 to dirs.Count - 1 do begin      FTP.ChangeWorkingDir(dirs[i]);        ListAllFiles(dirs[i]);    end;    end;  finally    dirs.Free;  end;end; Or: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TFtpSync.ListAllFiles(const aDir: string);var  i: integer;  s: string;  dirs: TStringList;begin  dirs := nil;  try    FTP.List(aDir, false);    for i := 0 to FTP.FtpList.Count - 1 do begin      s := FTP.FtpList[i].FileName;      WriteLn(aDir + '/' + s);      if FTP.FtpList[i].Directory then begin        if dirs = nil then        dirs := TStringList.Create;        dirs.Add(s);      end;    end;    if dirs <> nil then begin      for i := 0 to dirs.Count - 1 do begin      FTP.ChangeWorkingDir(dirs[i]);        ListAllFiles(dirs[i]);      FTP.ChangeToParentDir;      end;    end;  finally    dirs.Free;  end;end; ---------------------------------------------------------------------- Hellios · 2017-06-30 23:54 Quote from: Remy Lebeau on July 01, 2017, 12:11:38 amThink 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.