Page 2 of 3
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Tue Feb 22, 2011 3:05 pm
by Demivec
MachineCode wrote:Doesn't work if I specify "C:\" as the root folder, but it seems to be searching?
Code: Select all
count = FindFiles(@MyCallBack(),"C:\", "*.exe|*.dll|*.txt",1)
Add this at about line 15:
Code: Select all
If Right(StartDirectory, 1) = "\"
StartDirectory = Left(StartDirectory, Len(StartDirectory) - 1)
EndIf
In the original code StartDirectory is not supposed to end with a "\", this change handles that possibility.
Another thing to note is that filename patterns with the "*" wildcard will produce only rough matches. For instance, if a pattern is specified as "*.exe" then any filename with ".exe" in it will be found also (i.e. "file.exe.something"), not just ones ending in ".exe".
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Tue Feb 22, 2011 3:22 pm
by TerryHough
See my editted NOTE about the code above.
The code is case sensitive, so the comparison results may not be what is expected.
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Tue Feb 22, 2011 9:53 pm
by TerryHough
Try this method. It seems to be working OK and fast to me. Improvements ideas welcome.
Code: Select all
Procedure RecursivelyExploreDirectory(SourceDirectory$, Start, Pattern$)
If ExamineDirectory(Start, SourceDirectory$, "*.*")
While NextDirectoryEntry(Start)
Select DirectoryEntryType(Start)
Case #PB_DirectoryEntry_Directory
If DirectoryEntryName(Start) <> "." And DirectoryEntryName(Start) <> ".."
a$ = SourceDirectory$+DirectoryEntryName(Start)+"\"
Start+1
RecursivelyExploreDirectory(a$, Start, Pattern$)
FinishDirectory(Start) ; REMOVE THIS LINE (BUG)
ExplorerListGadget(0, 0, 0, 0, 0, a$ + pattern$, #PB_Explorer_NoFolders | #PB_Explorer_NoParentFolder)
If CountGadgetItems(0) > 0
Count + CountGadgetItems(0)
;Do whatever you need to with the resulting explorer file list
;MessageRequester("Find Files", a$ + #LF$ + Str(CountGadgetItems(0)) + " in folder" + #LF$ + Str(count) + " total files", #MB_ICONINFORMATION)
EndIf
Start-1
EndIf
EndSelect
Wend
FinishDirectory(Start)
ExplorerListGadget(0, 0, 0, 0, 0, SourceDirectory$ + Pattern$, #PB_Explorer_NoFolders | #PB_Explorer_NoParentFolder)
If CountGadgetItems(0) > 0
Count + CountGadgetItems(0)
;Do whatever you need to with the resulting explorer file list
;MessageRequester("Find Files", SourceDirectory$ + #LF$ + Str(CountGadgetItems(0)) + " in folder" + #LF$ + Str(count) + " total files", #MB_ICONINFORMATION)
EndIf
EndIf
ProcedureReturn Count
EndProcedure
SetCurrentDirectory("C:\folder\")
If OpenWindow(0, 0, 0, 400, 200, "ExplorerListGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Files.l = RecursivelyExploreDirectory(GetCurrentDirectory(),1,"*.exe;*.dll;*.com")
MessageRequester("Find Files", "Total " + GetCurrentDirectory() + #LF$ + Str(Files) + " files", #MB_ICONINFORMATION)
; Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
End
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Wed Feb 23, 2011 6:06 am
by Suirad
i prefer this method, its very similar to the pattern array by Rook Zimbabwe.
Code: Select all
For x=1 To 3
Select x
Case 1
dir=ExamineDirectory(#PB_Any,"C:\","*.jpg")
While NextDirectoryEntry(dir)
Debug DirectoryEntryName(dir)
Wend
FinishDirectory(dir)
Case 2
dir=ExamineDirectory(#PB_Any,"C:\","*.rar")
While NextDirectoryEntry(dir)
Debug DirectoryEntryName(dir)
Wend
FinishDirectory(dir)
Case 3
dir=ExamineDirectory(#PB_Any,"C:\","*.gif")
While NextDirectoryEntry(dir)
Debug DirectoryEntryName(dir)
Wend
FinishDirectory(dir)
EndSelect
Next
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Wed Feb 23, 2011 2:31 pm
by kenmo
OK, it looks like there is no way to specify multiple types directly in ExamineDirectory() (like OpenFileRequester(), etc...)
But we have about 5 or 6 other methods here for reference, thanks guys.
I will keep using my RegEx method on the first page for now, but if speed becomes an issue on 2000+ files, maybe I'll run some speed tests and see if any method is noticeably faster.
Thanks everyone!
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Mon Feb 28, 2011 3:00 am
by IdeasVacuum
Hi Terry
Can't figure out your code, it halts immediately on line 13:
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Mon Feb 28, 2011 8:37 pm
by TerryHough
@IdeasVacumn
Can't duplicate that here with Win XP Pro.
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Mon Feb 28, 2011 9:12 pm
by kenmo
I get the same error, (PB 4.51 XP Pro) but not immediately. Stick a
Debug SourceDirectory$ at the top of the procedure, and it seems to be failing on the third recursive folder for me... not sure why yet...
Also I'll mention that I actually switched BACK from using the nifty RegExp method to the simple loop method:
Code: Select all
Examine All Files (*.*)
Foreach File
Match = False
Foreach Extension
Check File Extension Match, break if true
Next
If Match, Process File...
Next
Two reasons: (A) Using the RegEx library requires you include the license text/file and (B) the library increases the executable size ~30% (overkill for this simple use).
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Tue Mar 01, 2011 12:19 am
by TerryHough

Fails with the Debugger running
Turn off the Debugger and it runs perfectly. Strange?
I rarely use the Debugger so I had never seen this.
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Tue Mar 01, 2011 10:37 am
by Vera
Hello,
I also experienced this IMA on Win and Linux but found the reason today.
The
FinishDirectory(Start) in line 13 is a)- double
(see line 25) and b)- prevents the processing of the following code
(I never got count-results). Just comment it out and and the code runs fine.
Note: the ExplorerListGadget(0, 0, 0, 0, 0 ... doesn't show much because it's sized to zero
Thanks for this stretching thread
Vera
ps:
kenmo wrote:it seems to be failing on the third recursive folder for me... not sure why yet...
it always failed the moment there was nomore further sub-directory
There's one thing puzzling me:
Is it common or proper to call a current procedure from within itself ? I thought this would result into an infinite loop.
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Tue Mar 01, 2011 3:43 pm
by Trond
Vera wrote:There's one thing puzzling me:
Is it common or proper to call a current procedure from within itself ? I thought this would result into an infinite loop.
This is called recursion, and it's perfectly fine as long as the procedure knows when to stop calling itself.
Code: Select all
Procedure RecursiveProcedure(A, N)
If N = 0
; Not calling itself
ProcedureReturn A
Else
; Calling itself, but decreasing N so that it will eventually stop
ProcedureReturn RecursiveProcedure(A*2, N-1)
EndIf
EndProcedure
Debug RecursiveProcedure(2, 6)
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Tue Mar 01, 2011 5:03 pm
by TerryHough
Vera wrote:The FinishDirectory(Start) in line 13 is a)- double and b)- prevents the processing of the following code . Just comment it out and and the code runs fine.
Good catch
Vera wrote:
Note: the ExplorerListGadget(0, 0, 0, 0, 0 ... doesn't show much because it's sized to zero
On purpose. It prevents screen-flicker in this case since the ExplorerGadget's display is never being used and is immediately replaced with another. Agree it is an odd construct. I tried Hiding the ExplorerGadget immediately but it still flickered, so this was my solution. It could also be positioned outside the main window's space.
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Thu Mar 03, 2011 9:17 pm
by peterb
Hi,
you can use this procedure for multiple file extensions
Code: Select all
EnableExplicit
Procedure DirectoryListing ( Directory.s, ExtensionMask.s, Recursive = #False )
Protected FileName.s
Protected FullFileName.s
Protected MyDir = ExamineDirectory ( #PB_Any, Directory, "*.*" )
ExtensionMask = LCase ( ExtensionMask )
If MyDir
Repeat
If NextDirectoryEntry ( MyDir ) = 0 : Break : EndIf
If Right ( Directory, 1 ) <> "\"
Directory = Directory + "\"
EndIf
FileName = DirectoryEntryName ( MyDir )
FullFileName = Directory + FileName
If FileName <> "." And FileName <> ".."
If DirectoryEntryType ( MyDir ) = #PB_DirectoryEntry_Directory
If recursive = #True
DirectoryListing ( FullFileName, ExtensionMask, Recursive )
EndIf
Else
If FindString ( ExtensionMask, "." + LCase ( GetExtensionPart ( FileName ) ) + ";", 1 )
; -----------------------
Debug FullFileName
; -----------------------
EndIf
EndIf
EndIf
ForEver
FinishDirectory ( MyDir )
EndIf
EndProcedure
DirectoryListing ( "c:\windows\system32", ".exe;.dll;", #True )
peterb
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Thu Mar 03, 2011 10:04 pm
by TerryHough
peterb wrote:Hi, you can use this procedure for multiple file extensions
Close, but has a problem. Your routine is recursively examining the directories but is not finding matching files beyond the initial directory. Any files in sub-directories are missed.
Hint: Allowing MyDir to be set by the #PB_Any in the ExamineDirectory() is killing your seek. You must control the #Directory yourself to allow recursion.
Re: Multiple file extensions in ExamineDirectory() ?
Posted: Sat Mar 05, 2011 5:22 pm
by Vera
@Trond ~ @TerryHough
sorry I couldn't reply earlier - but I was heavily fighting with the codes
Thanks for the recursion example which is very descriptive to track
TerryHough wrote:Vera wrote:
Note: the ExplorerListGadget(0, 0, 0, 0, 0 ... doesn't show much ... o

On purpose. It prevents screen-flicker in this case since the ExplorerGadget's display is never being used...
I see - and realised that I got trapped thinking I'd get a result-view of found files. So I enhanced your code in that sense to gain an optical
(flicker-free) output.
By this, one can crosscheck the results and I now stumbled across the amount of 'Count'-results which can vary strangely and do not allow to allocate which selection they concern. The hits mostly fit
(although I've seen rare misscountings there as well). I haven't figured out why this happens - if it's because 'Count' is prossed twice or due to Windows special habits with the asterix (*).
Could you have a look if you experience something similar like: 3 found files / total Count 190 files - while there are only 20 files inside the folder (w/o sub) and the summed up found files is also far below this amount.
greetings ~ Vera
Code: Select all
Global item, count2
Procedure RecursivelyExploreDirectory(SourceDirectory$, Start, Pattern$)
If ExamineDirectory(Start, SourceDirectory$, "*.*")
Debug SourceDirectory$
While NextDirectoryEntry(Start)
Select DirectoryEntryType(Start)
Case #PB_DirectoryEntry_Directory
If DirectoryEntryName(Start) <> "." And DirectoryEntryName(Start) <> ".."
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
a$ = SourceDirectory$+DirectoryEntryName(Start)+"/"
CompilerElse
a$ = SourceDirectory$+DirectoryEntryName(Start)+"\"
CompilerEndIf
Start+1
RecursivelyExploreDirectory(a$, Start, Pattern$)
ExplorerListGadget(0, 0, 0, 400, 100, a$ + pattern$, #PB_Explorer_NoFolders | #PB_Explorer_NoParentFolder)
If CountGadgetItems(0) > 0
Count + CountGadgetItems(0)
;Do whatever you need to with the resulting explorer file list
; MessageRequester("Find Files", a$ + #LF$ + Str(CountGadgetItems(0)) + " matches in folder" + #LF$ + Str(Count) + " total files (of what ?) "); , #MB_ICONINFORMATION
EndIf
Start-1
EndIf
EndSelect
Wend
FinishDirectory(Start)
ExplorerListGadget(0, 0, 0, 400, 100, SourceDirectory$ + Pattern$, #PB_Explorer_NoFolders | #PB_Explorer_NoParentFolder) ; ,
If CountGadgetItems(0) > 0
Count + CountGadgetItems(0)
colo = RGB(Random(155)+100, Random(155)+100, Random(155)+100)
For n=0 To CountGadgetItems(0)-1
file$ = GetGadgetItemText(0, n)
spath$ = RemoveString(GetGadgetText(0), GetCurrentDirectory())
AddGadgetItem(item, -1, file$ +Chr(10)+ GetExtensionPart(file$)+Chr(10)+ spath$)
SetGadgetItemColor(item, CountGadgetItems(item)-1, #PB_Gadget_BackColor, colo , 2)
SetGadgetState(item, CountGadgetItems(item)-1)
Debug file$
Next n
count2 + n
Debug Count
Debug count2
AddKeyboardShortcut(0, #PB_Shortcut_Space, 0) ; Spacekey to skip timeout
startTime=ElapsedMilliseconds()
Repeat
wwe = WaitWindowEvent(100)
If wwe = #PB_Event_CloseWindow : End : EndIf
If wwe = #PB_Event_Menu And EventMenu() = 0 : startTime =0 : EndIf
Until ElapsedMilliseconds()-startTime > 1300 ; en-/decrease timeout for listupdate
; Do whatever you need to with the resulting explorer file list
; MessageRequester("Find Files of: " + Pattern$ , SourceDirectory$ + #LF$ + Str(CountGadgetItems(0)) + " matches in folder" + #LF$ + Str(Count) + " total files (of what ?)" + #LF$+ #LF$ + Str(count2) + " summed finds") ; , #MB_ICONINFORMATION
EndIf
EndIf
ProcedureReturn Count
EndProcedure
dir$ = #PB_Compiler_Home
;dir$ = "C:\"
;dir$ = "/home"
SetCurrentDirectory(dir$)
Pattern$ = "*.exe;*.txt;*.png"
If OpenWindow(0, 130, 130, 400, 405, "ExplorerListGadget", #PB_Window_SystemMenu ) ; | #PB_Window_ScreenCentered
item = ListIconGadget(#PB_Any, 0, 100, 400, 300, "Files", 135, #PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection)
AddGadgetColumn(item, 1, "Ext", 35)
AddGadgetColumn(item, 2, GetCurrentDirectory(), 210)
Files.l = RecursivelyExploreDirectory(GetCurrentDirectory(),1, Pattern$)
MessageRequester("Find Files by: "+ Pattern$, "Total "+ #LF$ + GetCurrentDirectory()+ #LF$+#LF$+ Str(Files)+ " files"+ #LF$ + Str(count2)+ " summed finds") ; , #MB_ICONINFORMATION
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
End