Re: cFileSearch by Ulrich Korndoerfer
- From: Ulrich Korndoerfer <ulrich_wants_nospam@xxxxxxxxxxxx>
- Date: Tue, 25 Nov 2008 00:11:18 +0100
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/
.
- Follow-Ups:
- OT: (for everyone)
- From: DanS
- Re: cFileSearch by Ulrich Korndoerfer
- From: MP
- OT: (for everyone)
- References:
- cFileSearch by Ulrich Korndoerfer
- From: MP
- cFileSearch by Ulrich Korndoerfer
- Prev by Date: Re: cFileSearch by Ulrich Korndoerfer
- Next by Date: Re: media player problem
- Previous by thread: Re: cFileSearch by Ulrich Korndoerfer
- Next by thread: Re: cFileSearch by Ulrich Korndoerfer
- Index(es):
Relevant Pages
|