Function to Return Directory Names
QUESTION: I am running IDL on a Windows machine. Can you show me how to write a recursive function to return all the directories that are rooted at a target directory?
ANSWER: This newsgroup question took me longer to respond to than I planned. These darn recursive functions always seem to confuse me. In struggling with this question, I kept getting multiple copies of the same directory in my return value. As you can see, I finally resorted to putting up with that behavior and returning only the unique values.
Please note that this example code is specific for Windows machines only and that it uses features of IDL 5.1. It should not be too hard to generalize for UNIX and Macintosh computers, but VMS could cause a few problems. In any case, I leave that as an exercise for the reader.
Here is the example code. If you are on a Windows machine, you can type this to see all the directories that are rooted at your current directory:
IDL> Print, AllDir()
Function AllDir, target ; This function returns the names of all the directories ; rooted at the "target" directory. The function is specific ; for the Windows operating system. The return names are ; given with respect to the target name. On_Error, 1 ; Default directory is current directory. IF N_Params() EQ 0 THEN BEGIN CD, Current=target target = target + '\' ENDIF ; Check to see if target argument is a string. variableType = Size(target, /Type) IF variableType NE 7 THEN $ Message, 'Argument must be STRING type.' ; Move to target directory. CD, target, Current=thisDirectory ; Find the files in the target directory. theseFiles = Findfile('*', Count=count) IF count EQ 0 THEN RETURN, '' ; Find the directories in the file list. Directories ; end with a "\" character. endCharPos = StrLen(theseFiles) - 1 FOR j=0,count-1 DO BEGIN IF theseFiles[j] NE '.\' AND theseFiles[j] NE '..\' THEN BEGIN lastChar = StrMid(theseFiles[j], endCharPos[j], 1) IF lastChar EQ '\' THEN BEGIN IF N_Elements(theseDirs) EQ 0 THEN $ theseDirs = [theseFiles[j], AllDir(theseFiles[j])] ELSE $ theseDirs = [theseDirs, theseFiles[j], AllDir(theseFiles[j])] ENDIF ENDIF ELSE theseDirs = '' ENDFOR ; Add the target directory to each directory name. theseDirs = target + theseDirs ; Move back to the starting directory. CD, thisDirectory ; Remove null strings and non-unique values. theseDirs = theseDirs[Where(theseDirs NE target) > 0] theseDirs = theseDirs[Uniq(theseDirs)] ; Return the list. RETURN, theseDirs END
Copyright © 1998 David W. Fanning
Last Updated 3 June 1998