FindMultipleFiles() » wildcards, recursivity, callback...

Share your advanced PureBasic knowledge/code with the community.
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

FindMultipleFiles() » wildcards, recursivity, callback...

Post 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").
Last edited by AND51 on Thu Nov 15, 2007 12:35 am, edited 3 times in total.
PB 4.30

Code: Select all

onErrorGoto(?Fred)
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post 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. :wink:
PB 4.30

Code: Select all

onErrorGoto(?Fred)
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post 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
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post 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)
PB 4.30

Code: Select all

onErrorGoto(?Fred)
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post 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.
PB 4.30

Code: Select all

onErrorGoto(?Fred)
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post 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!
PB 4.30

Code: Select all

onErrorGoto(?Fred)
kinglestat
Enthusiast
Enthusiast
Posts: 746
Joined: Fri Jul 14, 2006 8:53 pm
Location: Malta
Contact:

Post by kinglestat »

nice code
I had done something similar, but I like your approach
I may not help with your coding
Just ask about mental issues!

http://www.lulu.com/spotlight/kingwolf
http://www.sen3.net
kinglestat
Enthusiast
Enthusiast
Posts: 746
Joined: Fri Jul 14, 2006 8:53 pm
Location: Malta
Contact:

Post 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
I may not help with your coding
Just ask about mental issues!

http://www.lulu.com/spotlight/kingwolf
http://www.sen3.net
Post Reply