Multiple file extensions in ExamineDirectory() ?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Multiple file extensions in ExamineDirectory() ?

Post 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".
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Re: Multiple file extensions in ExamineDirectory() ?

Post 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.
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Re: Multiple file extensions in ExamineDirectory() ?

Post 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 
Last edited by TerryHough on Sat Mar 05, 2011 8:45 pm, edited 1 time in total.
Suirad
User
User
Posts: 42
Joined: Sun Sep 20, 2009 7:37 pm
Location: Melbourne, Florida, USA

Re: Multiple file extensions in ExamineDirectory() ?

Post 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
User avatar
kenmo
Addict
Addict
Posts: 2033
Joined: Tue Dec 23, 2003 3:54 am

Re: Multiple file extensions in ExamineDirectory() ?

Post 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!
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Multiple file extensions in ExamineDirectory() ?

Post by IdeasVacuum »

Hi Terry

Can't figure out your code, it halts immediately on line 13:

Code: Select all

FinishDirectory(Start)
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Re: Multiple file extensions in ExamineDirectory() ?

Post by TerryHough »

@IdeasVacumn
Can't duplicate that here with Win XP Pro.
User avatar
kenmo
Addict
Addict
Posts: 2033
Joined: Tue Dec 23, 2003 3:54 am

Re: Multiple file extensions in ExamineDirectory() ?

Post 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).
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Re: Multiple file extensions in ExamineDirectory() ?

Post 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.
User avatar
Vera
Addict
Addict
Posts: 858
Joined: Tue Aug 11, 2009 1:56 pm
Location: Essen (Germany)

Re: Multiple file extensions in ExamineDirectory() ?

Post 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.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Multiple file extensions in ExamineDirectory() ?

Post 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)
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Re: Multiple file extensions in ExamineDirectory() ?

Post 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.
peterb
User
User
Posts: 60
Joined: Sun Oct 02, 2005 8:55 am
Location: Czech Republic
Contact:

Re: Multiple file extensions in ExamineDirectory() ?

Post 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
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Re: Multiple file extensions in ExamineDirectory() ?

Post 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.
User avatar
Vera
Addict
Addict
Posts: 858
Joined: Tue Aug 11, 2009 1:56 pm
Location: Essen (Germany)

Re: Multiple file extensions in ExamineDirectory() ?

Post 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
Post Reply