Page 1 of 1
FindMultipleFiles() » wildcards, recursivity, callback...
Posted: Tue Nov 13, 2007 11:32 pm
by AND51
...and case-in-sensivity
Hello!
I updated the code for the 4th time. Please, have a look at the 4th code in this thread. It now supports callbacks.
[Old Post]
Hello!
// Edit: my second code below finds more than just the first file.
I just created a code that I wanted to post into the german forum.
This code searches for the first file matching the given parameter:
Code: Select all
; AND51
; Nov-2007
; For free use, credits appreciated
Procedure.s FindFile(file.s, directory.s, recursive=1)
PathAddBackslash_(@directory)
Protected result.s, dir=ExamineDirectory(#PB_Any, directory, file)
If dir And NextDirectoryEntry(dir)
result=directory+DirectoryEntryName(dir)
FinishDirectory(dir)
ElseIf recursive
dir=ExamineDirectory(#PB_Any, directory, "")
If dir
While NextDirectoryEntry(dir) And Not result
If DirectoryEntryType(dir) = #PB_DirectoryEntry_Directory And DirectoryEntryName(dir) <> "." And DirectoryEntryName(dir) <> ".."
result=FindFile(file, directory+DirectoryEntryName(dir), 1)
EndIf
Wend
FinishDirectory(dir)
EndIf
EndIf
ProcedureReturn result
EndProcedure
Debug FindFile("hiberfil.sys", "C:", 1)
- Case-In-Sensivity
- Recursive search is optional
- Wildcards can be used
- Intelligent search algorithm: Before entering any sub-directory, the current directory is being examined for the file. Normal codes instantly enter a subdirectory if it comes alphabetically before the filename
Edit:
Improved the pattern at
ExamineDirectory(), should now work.
I removed the star (wildcard), otherweise he could fint "purebasic.exe", although you want to search for "basic.exe").
Posted: Wed Nov 14, 2007 10:52 am
by AND51
Feed this procedure with a LinkedList of the type "string" and my procedure will feed your list with all found files.
Moreover, the procedure returns the amount of results and benefits from the advantages of my code above.
This means, that the following code also supports case-in-sensivity, optional recursivity and wildcards.
Code: Select all
; AND51
; Nov-2007
; For free use, credits appreciated
EnableExplicit
Procedure FindMultipleFiles(file.s, directory.s, ResultList.s(), recursive=1)
PathAddBackslash_(@directory)
Protected dir=ExamineDirectory(#PB_Any, directory, file)
If dir
While NextDirectoryEntry(dir)
AddElement(ResultList())
ResultList()=directory+DirectoryEntryName(dir)
Wend
FinishDirectory(dir)
EndIf
If recursive
dir=ExamineDirectory(#PB_Any, directory, "")
If dir
While NextDirectoryEntry(dir)
If DirectoryEntryType(dir) = #PB_DirectoryEntry_Directory And DirectoryEntryName(dir) <> "." And DirectoryEntryName(dir) <> ".."
FindMultipleFiles(file, directory+DirectoryEntryName(dir), ResultList(), 1)
EndIf
Wend
FinishDirectory(dir)
EndIf
EndIf
ProcedureReturn CountList(ResultList())
EndProcedure
NewList suche.s()
Debug FindMultipleFIles("*.htm", "C:", suche(), 1)
ForEach suche()
Debug suche()
Next
suche (geman) = search (englisch)
I was too lazy to translate the word in the code.

Posted: Wed Nov 14, 2007 3:58 pm
by pdwyer
so the first one only finds a single file? (per dir?)
Should recursion on the first one work and return the first file back per directory, I'm not sure I understand why you'd want that.
The second post seems fine but the first one
Debug FindFile("*.txt", "C:", 1)
Debug FindFile("*.txt", "C:", 0)
return only one file even though there are 6 in just C root and many others in other directories so recursions failing and I don't see the point of the parameter
Posted: Wed Nov 14, 2007 4:36 pm
by AND51
Yes, you understood right.
FindFile() should only return the first file that is being found.
I don't know the exact reason, why it should be like this. One of the german forum members took an old code from the code-archiv and prepared it for PB 4. I took his code an optimized it.
I even optimized it a second time: FindMultipleFiles()
And I even improved it a third time: I added an optional callback! (see code in my next post)
Posted: Wed Nov 14, 2007 4:41 pm
by AND51
FindMultipleFiles() »»» Callback, Wildcards, CaseInSensivity, Intelligent Search (saves time)
Code: Select all
; AND51
; Nov-2007
; For free use, credits appreciated
EnableExplicit
Procedure myPersonalCallback(CurrentDir$)
If MessageRequester("FindMultipleFiles()", CurrentDir$+#CRLF$+"Dies könnte dein Callback sein. Suche beenden?"+#CRLF$+"This could be your callback. Abort search?", #MB_ICONINFORMATION|#PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
; Abort Search
ProcedureReturn 0
Else
; Continue
ProcedureReturn 1
EndIf
EndProcedure
Procedure FindMultipleFiles(file.s, directory.s, ResultList.s(), recursive=1, *callback=0)
PathAddBackslash_(@directory)
If *callback
If CallFunctionFast(*callback, directory) = 0
ProcedureReturn -1
EndIf
EndIf
Protected dir=ExamineDirectory(#PB_Any, directory, file)
If dir
While NextDirectoryEntry(dir) And recursive <> -1
AddElement(ResultList())
ResultList()=directory+DirectoryEntryName(dir)
Wend
FinishDirectory(dir)
EndIf
If recursive
dir=ExamineDirectory(#PB_Any, directory, "")
If dir
While NextDirectoryEntry(dir)
If DirectoryEntryType(dir) = #PB_DirectoryEntry_Directory And DirectoryEntryName(dir) <> "." And DirectoryEntryName(dir) <> ".."
If FindMultipleFiles(file, directory+DirectoryEntryName(dir), ResultList(), 1, *callback) = -1
Break
EndIf
EndIf
Wend
FinishDirectory(dir)
EndIf
EndIf
ProcedureReturn CountList(ResultList())
EndProcedure
NewList suche.s()
Debug FindMultipleFIles("*.sys", "C:", suche(), 1, @myPersonalCallback())
ForEach suche()
Debug suche()
Next
You now have the possibility to add a callback. The calback should have 1 string-parameter (for the current directory). If the callback returns 0, the search will be stopped; otherwise the search is being continued. You can leave out the callback; if callback = 0, then no callback will be used.
Recursivity is also optional.
Returnings: -1 if the procedure was stopped by a callback, any other number represent the amount of results.
Posted: Wed Nov 14, 2007 9:31 pm
by AND51
FindMultipleFiles() »»» Now supports search for multiple files at once
You can search for *.pb, *.sys and purebasic*.exe files at once!
You just have to seperate each file with a vertical line | just as you do at
OpenFileRequester().
Note: If Fred had implemented multiple-pattern-support for
ExamineDirectory() this update would not be necessary.
Code: Select all
; AND51
; Nov-2007
; For free use, credits appreciated
EnableExplicit
Procedure myPersonalCallback(CurrentDir$)
If MessageRequester("FindMultipleFiles()", CurrentDir$+#CRLF$+"Dies könnte dein Callback sein. Suche beenden?"+#CRLF$+"This could be your callback. Abort search?", #MB_ICONINFORMATION|#PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
; Abort Search
ProcedureReturn 0
Else
; Continue
ProcedureReturn 1
EndIf
EndProcedure
Procedure FindMultipleFiles(files.s, directory.s, ResultList.s(), recursive=1, *callback=0) ; use | to seperate files!
PathAddBackslash_(@directory)
If *callback
If CallFunctionFast(*callback, directory) = 0
ProcedureReturn -1
EndIf
EndIf
Protected dir, i, n=CountString(files, "|")+1
For i=1 To n
dir=ExamineDirectory(#PB_Any, directory, StringField(files, i, "|"))
If dir
While NextDirectoryEntry(dir) And recursive <> -1
AddElement(ResultList())
ResultList()=directory+DirectoryEntryName(dir)
Wend
FinishDirectory(dir)
EndIf
Next
If recursive
dir=ExamineDirectory(#PB_Any, directory, "")
If dir
While NextDirectoryEntry(dir)
If DirectoryEntryType(dir) = #PB_DirectoryEntry_Directory And DirectoryEntryName(dir) <> "." And DirectoryEntryName(dir) <> ".."
If FindMultipleFiles(files, directory+DirectoryEntryName(dir), ResultList(), 1, *callback) = -1
Break
EndIf
EndIf
Wend
FinishDirectory(dir)
EndIf
EndIf
ProcedureReturn CountList(ResultList())
EndProcedure
NewList suche.s()
Debug FindMultipleFiles("*.pb*|purebasic_compilation*|purebasic.exe", "D:", suche(), 1, @myPersonalCallback())
ForEach suche()
Debug suche()
Next
This example searches for
- *.pb* (pb, pbi, pbv, ...)
purebasic_compilation* (compiled pb exe's)
purebasic.exe (pb ide)
at once!
Posted: Thu Nov 22, 2007 12:35 am
by kinglestat
nice code
I had done something similar, but I like your approach
Posted: Thu Nov 22, 2007 12:38 am
by kinglestat
and I think fred tries his best to use the OS base APIs which tend to be the fastest...and up to us to use them as best as possible