Jakob Hede Madsen wrote
>> Can anyone tell me how to run a "repeat loop" which will list all the
>> subdirectories when supplied the drive name. for e.g. if i supply the drive
>> name as "c:\", the program should return all the subdirectories beneath it in
>> the form of a tree.
>
> Well, a tree is not exactly one of directors native types, but here's my stab:
> It uses FileXtra3.
> It returns a nested property list which constitutes a "tree".
> Hope this can be of inspiration.
Using a repeat loop and recursively calling a handler is very quick, but if
you are doing it on a root directory of a big hard drive with thousands of
directories, then it can be slow and lock out the end user whilst its going
through the repeat loop - and possibly have memory problems.
A much slower but less aggressive approach is to step though a directory on
stepFrame or some similar repeating event. To do this, you basically need a
'bread crumb trail' so that whenever you've finished a sub directory, you
can back up to the parent directory and continue searching true that.
If you are interested, heres a script object for getting a nested list of
directories and their subdirectories (its a 'first draft script' that I
never actually used. I'm sure it works but, but it could probably be
optimised significantly)
_________________________________________________________________________
-- Parent script: Threaded directory lister
-- Dependencies: FileXtra
_________________________________________________________________________
property myResultList -- proplist: the directory 'tree'
property mySep -- string: path sep
property myRootPath -- string: root directory of the search
property myCurrentIndex -- integer: index of current directory list
property myCurrentDepthTrail -- list: current path through tree
property myCurrentDir -- string: current directory being listed
property myTimeoutName -- string: name of timeout object
property myCallback -- Symbol or string: callback method or handler
property myCallBackObj -- objectRef: object to send myCallback to
----------------------------- // Create and Destroy
on new (me, pRootPath, pCallback, pCallBacktarget)
myCallback = pCallback
myCallBackObj = pCallBacktarget
mySep = the last char of the moviePath
myTimeoutName = string(me)
me.mInit(pRootPath)
return me
end
on destroy (me)
timeout(myTimeoutName).forget()
pCallBacktarget = VOID
end
----------------------------- // Additional interface
on mGetStatus (me)
return ("Searching " & myRootPath & myCurrentDir)
end
on mGetResultList (me)
return myResultList
end
on mPauseSearch me
timeout(myTimeoutName).forget()
end
on mContinueSearch me
timeout(myTimeoutName).new(1, #mRunthread, me)
end
----------------------------- // Private
on mInit (me, pRootPath)
myRootPath = pRootPath
myCurrentIndex = 0
myCurrentDepthTrail = []
myCurrentDir = ""
myResultList = me.mGetDirList(myRootPath)
----
timeout(myTimeoutName).new(1, #mRunthread, me)
end
on mRunThread (me)
currentDirectoryList = myResultList
repeat with branchPoint in myCurrentDepthTrail
currentDirectoryList = currentDirectoryList[BranchPoint]
end repeat
myCurrentIndex = myCurrentIndex + 1
if myCurrentIndex > currentDirectoryList.count then
-- finished with current sublist
if myCurrentDepthTrail.count > 0 then
-- close current branch, and revert to previous node
myCurrentIndex = myCurrentDepthTrail[myCurrentDepthTrail.count]
myCurrentDepthTrail.deleteAt(myCurrentDepthTrail.count)
the itemDelimiter = mySep
lastItem = myCurrentDir.item.count
if lastItem > 2 then myCurrentDir = myCurrentDir.item[1..lastItem-2] &
mySep
else myCurrentDir = ""
else
-- finished the root directory
if symbolP(myCallback) and objectP(myCallBackObj) then
call(myCallback, myCallBackObj, myResultList)
else if stringP(myCallback) then
do (myCallback & "("& myResultList & ")")
end if
me.destroy()
end if
else
-- still working through the current dir
thisEntry = currentDirectoryList.getPropAt(myCurrentIndex)
subDir = myCurrentDir & thisEntry
thisSubList = me.mGetDirList(myRootPath & subDir)
if thisSubList.count() then
-- open new branch
currentDirectoryList.setProp(thisEntry, thisSubList)
myCurrentDir = subDir
myCurrentDepthTrail.append(myCurrentIndex)
myCurrentIndex = 0
else
-- no sub directory
end if
end if
end
on mGetDirList (me, pPath)
dirList = [:]
tList = directoryToList(pPath)
repeat with anItem in tList
if the last char of anItem = mySep then
dirList.addProp(anItem, [:])
end if
end repeat
return dirList
end
----------------------------
-- example useage:
global gObj
on test aPath
gObj =script("DirectoryLister").new(aPath, "SearchDone")
end
on searchDone results
gObj = VOID
put results
end
on cancelSearch
gObj.destroy()
gObj = VOID
end
Luke
[To remove yourself from this list, or to change to digest mode, go to
http://www.penworks.com/LUJ/lingo-l.cgi To post messages to the list,
email [EMAIL PROTECTED] (Problems, email [EMAIL PROTECTED])
Lingo-L is for learning and helping with programming Lingo. Thanks!]