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!]

Reply via email to