Recent

Author Topic: Routine to array all folders from a base path  (Read 896 times)

Trivius

  • Newbie
  • Posts: 2
Routine to array all folders from a base path
« on: May 29, 2023, 09:03:23 am »
I really need and would appreciate help in completing a script routine that puts all directories and sub-directories into an array, using a top down approach that branches outward, while working to the bottom of the list.  My script language uses a command 'getDirList' that places all directories within a path into an array (i.e., I don't have access to any other functions that pertain to accessing directory data), if there are no directories located within a path it then returns as '0'.  I need to complete this routine as part of a larger script I'm working on that needs this function in order to grab, organize, and access all associated script files within a designated scripts directory.

I've been stuck working on resolving this for several weeks now and no longer feel that I can do this on my own.  There is something I am not understanding in managing the iterating of the arrays as the routine moves backwards and downwards, my returns are always erratic, skipping directories/sub-directories and/or getting arrays that are out of bounds.  I think the issue pertains to how to effectively increase and decrease the $c counter.

Here is where I am at currently with my code, I think I just need help with the logic necessary to accomplish this task, if it helps (as this is not a mainstream scripting language) as to alt languages I am familiar with PHP and JS, and am just starting to learn Pascal:

Code: Pascal  [Select][+][-]
  1. $SCRIPTSPATH := "C:\Scripts\"
  2. $folder_path := $SCRIPTSPATH
  3. $directories[1] := $SCRIPTSPATH
  4. $directories[1][1] := 1
  5. $i := 1
  6. $c := 1
  7.  
  8. (while loop...)
  9.  
  10.  goSub :GETDIRLIST
  11.  
  12.  if ($folders > 0) AND ($directories[$c][1] <= $folders)
  13. #  Appending folders here.
  14.   $c++
  15.   if ($directories[$c][1] = 0)
  16.    $directories[$c][1] := 1
  17.   end
  18.   $i++
  19.   $directories[$i] := $folder_path & $folders[$directories[$c][1]] & "\"
  20.   $folder_path := $directories[$i]
  21.   $directories[$c][1]++
  22.  else
  23.   if ($directories[$c][1] > $folders)
  24. #  Move backwards.
  25.   while ($directories[$c][1] > $folders)
  26.    $c--
  27.    $folder_path := $directories[$c]
  28.    goSub :GETDIRLIST
  29.   end
  30.   elseif ($folders = 0) AND ($directories[$c][1] <= $folders)
  31. #  At a deadend, so move downward.
  32.    $directories[$c][1]++
  33.   else
  34. #  Do nothing???
  35.   end
  36.  end
  37.  
  38. (end looping)
  39.  
  40. :GETDIRLIST
  41. getDirList $folders $folder_path
  42. return
« Last Edit: May 29, 2023, 11:32:31 am by Trivius »

Bart

  • Hero Member
  • *****
  • Posts: 5265
    • Bart en Mariska's Webstek
Re: Routine to array all folders from a base path
« Reply #1 on: May 29, 2023, 09:37:19 am »
You might want to take a look at the TSearcher class (or one of it's descendants) of Lazarus.

Bart

d4eva

  • New Member
  • *
  • Posts: 24
Re: Routine to array all folders from a base path
« Reply #2 on: May 29, 2023, 09:56:41 am »
You mean something like this?

Code: Pascal  [Select][+][-]
  1.  
  2. uses
  3. ...
  4. fileutil;
  5.  
  6.  
  7. procedure foo;
  8. var
  9.   ListOfFolders: TStringList;
  10.   i: integer;
  11. begin
  12.   Memo1.Lines.Clear;
  13.   ListOfFolders := TStringList.Create;
  14.   FileUtil.FindAllDirectories(ListOfFolders, 'd:\', True);
  15.   for i := 0 to ListOfFolders.Count - 1 do begin
  16.        Memo1.Lines.Add(ListOfFolders[i]);
  17.   end;
  18.   ListOfFolders.Free;
  19. end;
  20.  
  21.  

Bart

  • Hero Member
  • *****
  • Posts: 5265
    • Bart en Mariska's Webstek
Re: Routine to array all folders from a base path
« Reply #3 on: May 29, 2023, 10:21:59 am »
Optionally you might want to sort the stringlist.
Note: you can do a simple
Code: Pascal  [Select][+][-]
  1.   Memo1.Lines.Assign(ListOfFolders;
instead of the for loop.

And of course the memo is only needed if you want to have the list on screen, otherwise directly process the contents of ListOfFolders.

Bart

Trivius

  • Newbie
  • Posts: 2
Re: Routine to array all folders from a base path
« Reply #4 on: May 29, 2023, 11:46:50 am »
Thanks, but I cannot use any of those built in or add-on classes/functions as this is an internal script language, I only can use its defined commands, which primarily includes the above mentioned 'getDirList', the rest has to be manipulated by appending variables and through array management; also I can use math operators, if, elseif, else, while, etc., and 'goto' or 'goSub' in order to visit another section of code and return, sort of like calling a function.

So, I need to manually track where I am at each level of the directory structure, moving forward and down, then backout at each deadend, to continue moving downwards until the last directory is reached.

$folder_path is the current path information,
$folder is an array that holds the folder names and their index,
$i is the total count of folders,
$directories[$i] is an array holding the full directory paths that have been checked, in order from top to bottom, and following as they branch outwards
$c is the current location within the directory structure,
$directories[$c] is the folder name for the index being checked in relation to $c
$directories[$c][1] is the folder index being checked in relation to $c
« Last Edit: May 29, 2023, 11:56:04 am by Trivius »

jamie

  • Hero Member
  • *****
  • Posts: 6077
Re: Routine to array all folders from a base path
« Reply #5 on: May 29, 2023, 01:58:08 pm »
I don't know your script language and I really don't think it matters here.

 I will add that in most cases, a single capture of a directory dump will involve spaces to the left of each entry or some sort of special character to indicate the depth of the tree.

 This depth marker may only be applied to the folder entries at the start which means you need to cycle backwards for example until you reach a string entry that has one of these makers.
   
 For example, a root folder may have only one space and all following entries with no spaces, indicating sibilants/children of that folder, until you read another with another maker, most likely one that has more than the first in its list.

 If you populate a TTreeView with some items and then save it to file, you can examine it view a text editor and see how the indentation is being performed.

 Spaces or tabs chars are normally the added item.
The only true wisdom is knowing you know nothing

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2006
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Routine to array all folders from a base path
« Reply #6 on: May 29, 2023, 03:56:00 pm »
this is an internal script language
What is the relation to FreePascal?
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

BobDog

  • Sr. Member
  • ****
  • Posts: 394
Re: Routine to array all folders from a base path
« Reply #7 on: May 29, 2023, 05:39:07 pm »

Basic pascal console program.
For large folders it might take a few seconds.
If you insert your own path then:
Code: Pascal  [Select][+][-]
  1.  
  2.  uses
  3.   process,strutils;
  4.  
  5.   function dir(path:ansistring;flag:ansistring):ansistring;
  6.   var ans:ansistring=' ';
  7.   begin
  8.   RunCommand('cmd.exe', ['/c', 'dir '+flag,path], ans);
  9.   exit(ans);
  10.   end;
  11.  
  12.   type aos = array of ansistring;
  13.  
  14. var
  15. s:ansistring;
  16. path:ansistring='C:\Users\Computer\Desktop\fb\Borland\';
  17. myarray:aos=nil;
  18. i:integer;
  19.  
  20. begin
  21.  
  22. s:=dir(path,'*/AD /B /ON /S');
  23. //writeln(s);
  24. myarray:=SplitString(s,chr(10));
  25. for i:=low(myarray) to high(myarray) do writeln(i+1,'  ',myarray[i]);
  26. writeln('Press enter to exit . . .');
  27. readln;
  28. end.
  29.  

 

TinyPortal © 2005-2018