Re: cFileSearch by Ulrich Korndoerfer

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Hi,

MP schrieb:

I'm trying to use cFileSearch cls but am doing something wrong getting the correct subdirectory
when searchdepth = -1 (all sub dirs)
I'm getting back filenames where the file is out of sync with the folder in which it really exists

oFileSearch.search
oFileSearch.BuildTreeIndexes
For i = 0 To oFileSearch.DirsCount - 1
With oFileSearch.DirsTree(i)
For N = 0 To .FoundFilesCount - 1
colRtn.Add oFileSearch.GetDirPath(i) & "\" & .FoundFiles(N).Name
Next N
End With
Next i

anyone see what I'm doing wrong?
thanks
mark


You should use

colRtn.Add oFileSearch.GetDirPath(oFileSearch.DirIdxFromTreeIdx(i)) _
& "\" & .FoundFiles(N).Name

In your loop you use an index i to adress an dir entry in the DirsTree view of the Dirs list (by using oFileSearch.DirsTree(i)), but then to return the dirs path you use the same index to address a directory in the Dirs list (by using oFileSearch.GetDirPath(i)). However GetDirPath expects an index adressing an entry in the Dirs list, not an index for the DirsTree view on the Dirs list! So for GetDirPath in your case you must use oFileSearch.DirIdxFromTreeIdx(i) to "translate" an DirsTree index to a Dirs index.

Please note (copied from the accompanying source code of CFileSearch):

<cite>

'The Dirs list holds in its name member only the name of the dir.
'To get the path to the dir, call GetDirPath. *DirIdx must be an
'index to the Dirs list.*

'If AbsPath is True, it returns a path starting with StartPath,
'that is an absolute path to the dir, otherwise it returns a
'relative path starting with StartDir.

'The returned path does not have a trailing backslash!

Public Function GetDirPath(ByVal DirIdx As Long, _
Optional ByVal AbsPath As Boolean = True) As String
....
End Function

....

'Use it to get an index to the Dirs list from an index to
'the DirsTree view. Both indexes then reference the same dir.

Public Property Get DirIdxFromTreeIdx(ByVal DirTreeIdx As Long) As Long
....
End Property

....

'Use it to get an index to the DirsTree view from an index
'to the Dirs list. Both indexes then reference the same dir.

Public Property Get TreeIdxFromDirIdx(ByVal DirIdx As Long) As Long
....
End Property

</cite>

Some background information (also explained in the comments of CFileSearch's source code):

CFileSearch during a search collects all found directories in an array (I call it the Dirs list), *in the order they are detected during search*. Each method or property named Dirs* or having an index parameter named DirIdx uses and adresses entries in this array.

However the order the directories appear in the Dirs list is *not* reflecting the hierarchical order the dirs have in your filesystem, because the search algorithm first collects all subdirs in a dir, then collects the subdirs of the subdirs.

For example for a startdir StartDir:

StartDir
SubDir1
SubSubDir
SubDir2

the Dirs list after a full search has the entries

Index 0: StartDir
Index 1: SubDir1
Index 2: SubDir2
Index 3: SubSubDir

For getting a directory list reflecting the hierarchical order, one has to call after a search BuildTreeIndexes (that is what you did). This creates an index array for the Dirs list like such:

Index 0: 0 (points to StartDir)
Index 1: 1 (points to SubDir1)
Index 2: 3 (points to SubSubDir)
Index 3: 2 (points to SubDir2)

You iterate over this sequence by using DirsTree(i). Therefore for eg. i = 2 you get the dir data of the dir SubSubDir. Then you use the same index i for getting the dir's path by calling GetDirPath(i). However GetDirPath uses the Dirs list and therefore for i = 2 returns the path for the dir SubDir2, and you got a mismatch.

I choose to implement CFileSearch in such a way ("breadth first" search) because of performance reasons. Doing not a "drill down first" or "depth first" search is faster. In many cases the user is not interested in the hierarchical order of the dirs, eg. if he just searches for some files, so a "depth first" algorithm would be overkill.

However, if needed, the user also can have the dirs sorted in their hierarchical order. This can be achieved by calling BuildTreeIndexes, which generates an index array using a recursive algorithm. This one is very fast as it just shuffles around some long values. In fact I believe doing a "breadth first" search first and then create an index array is faster than doing a "depth first" search. My approach of course needs some memory for the additional index array, but the additional memory requirements are low: eg. for 10000 dirs 40000 Bytes.

The result is: CFileSearch has two methods for accessing dir data: one using the Dirs list, expecting a DirIdx index and one using the DirsTree view, expecting a DirTreeIdx index. AFAIR GetDirPath is the only method which only works with DirIdx and does not have a DirTreeIdx counter part. However the two properties DirIdxFromTreeIdx and TreeIdxFromDirIdx at any time allow translation, so for methods using the Dirs list only a DirTreeIdx can be used by calling DirIdxFromTreeIdx and vice versa.

Hope that did remove some possible confusion :-)

Btw, I have a newer, unpublished version of CFileSearch. May be I will publish it on my web site in the next weeks. I could add a GetDirPath property using the dirs tree view for the users convenience.

--
Ulrich Korndoerfer

VB tips, helpers, solutions -> http://www.proSource.de/Downloads/
.



Relevant Pages

  • Re: cFileSearch by Ulrich Korndoerfer
    ... Public Function GetDirPath(ByVal DirIdx As Long, ... collects the subdirs of the subdirs. ... For getting a directory list reflecting the hierarchical order, ... which generates an index array using a recursive algorithm. ...
    (microsoft.public.vb.general.discussion)
  • OT: (for everyone)
    ... Public Function GetDirPath(ByVal DirIdx As Long, ... collects the subdirs of the subdirs. ... For getting a directory list reflecting the hierarchical order, ... which generates an index array using a recursive algorithm. ...
    (microsoft.public.vb.general.discussion)
  • Re: Ulrich =?ISO-8859-15?Q?Kornd=F6rfer=27s_CFileSearch_clas?= =?ISO-8859-15?Q?s?=
    ... After a search the order of the dirs in the Dirs property is the order the dirs have been scanned. ... To get a "second" view on the dir data, which reflects the hierarchical order, BuildTreeIndexes has to be called. ... I decided to search childs first, because in many cases hierarchical order is not of interest and searching childs first is much faster and saves windows ressources. ...
    (microsoft.public.vb.general.discussion)
  • usage of /etc/group
    ... I want to allow a html author rwx access to /usr/local/www and all ... subdirs off it, ... public_html dirs), and making a special group for this user seemed the ...
    (comp.unix.bsd.freebsd.misc)
  • IO: creating dirs/files...
    ... I figured, just for the hell of it, why not write a java class that creates the dirs and the files that go inside the dirs??? ... and inside each one an index.jsp file and other files (and subdirs and files inside the subdirs..) what would be best approach here.. ...
    (comp.lang.java.help)