Page 1 of 3

Multiple file extensions in ExamineDirectory() ?

Posted: Sun Feb 20, 2011 8:14 pm
by kenmo
Hello guys,

I want to search through various folders for files of certain (multiple) extensions. Such as audio files: mp3, wav, m4a, etc.

Currently I am using a combination of ExamineDirectory with the usual filter "*.*", then using RegExps to check the extensions.

I know that in ExamineDirectory you can specify an extenstion such as "*.mp3", but I'm wondering if there is a way to specify multiple.

I tried "*.mp3;*.wav" (as used in FileRequesters()) and some similar formats, but none work.

Not a big deal, it would just remove the need to generate a bunch of file extension RegExps and to check them against hundreds of files that WON'T match.

Any ideas?

Re: Multiple file extensions in ExamineDirectory() ?

Posted: Sun Feb 20, 2011 8:28 pm
by ts-soft

Code: Select all

Directory$ = "C:\"
If ExamineDirectory(0, Directory$, "*.*")  
  While NextDirectoryEntry(0)
    If DirectoryEntryType(0) = #PB_DirectoryEntry_File
      Ext$ = UCase(GetExtensionPart(DirectoryEntryName(0)))
      Select Ext$
        Case "MP3", "FLAC", "WAV"
      EndSelect
    EndIf

  Wend
  FinishDirectory(0)
EndIf

Re: Multiple file extensions in ExamineDirectory() ?

Posted: Sun Feb 20, 2011 10:25 pm
by kenmo
That's the first way I was doing it. Currently I use something like this:

Code: Select all

CreateRegularExpression(0, "^.*\.(chm|exe)$")

If ExamineDirectory(0, GetCurrentDirectory(), "*.*")
  While NextDirectoryEntry(0)
    Name.s = DirectoryEntryName(0)
    If MatchRegularExpression(0, LCase(Name))
      Debug "Found: " + Name
    EndIf
  Wend
  FinishDirectory(0)
EndIf
They both work fine. I just thought that maybe if I could filter the files I want within ExamineDirectory(), neither of these would be needed.

I think this has been discussed before, and there wasn't really a simpler way to do it than these two methods.....

Re: Multiple file extensions in ExamineDirectory() ?

Posted: Mon Feb 21, 2011 12:13 am
by Rook Zimbabwe
would not the | character work as it does in the open or save file dialogs???

TESTING

Code: Select all

Directory$ = "C:\"   ; Lists all entries in the Windows directory (without the contents of sub-directories)
Dim Pattern.s(2)
Pattern(0) = "*."
Pattern(1) = "*.txt"
Pattern(2) = "*.*"

For xyz = 0 To 2
  If ExamineDirectory(0, Directory$, Pattern(xyz))  
    While NextDirectoryEntry(0)
      If DirectoryEntryType(0) = #PB_DirectoryEntry_File
        Type$ = " [File] "
      Else
        Type$ = " [Sub-Dir] "
      EndIf
      
      Debug DirectoryEntryName(0) + Type$ + "- Size in byte: " + Str(DirectoryEntrySize(0))
    Wend
    FinishDirectory(0)
  EndIf
Next
seems to work... checking again!

Re: Multiple file extensions in ExamineDirectory() ?

Posted: Mon Feb 21, 2011 1:04 am
by IdeasVacuum
Nope, can't get it to work here (XP x86 PB4.51)

Re: Multiple file extensions in ExamineDirectory() ?

Posted: Mon Feb 21, 2011 2:09 am
by IdeasVacuum
Using the For-Next loop works though, which is the next best thing :)

Re: Multiple file extensions in ExamineDirectory() ?

Posted: Mon Feb 21, 2011 3:03 am
by kenmo
I guess I'll just stick with my RegExp method :)

Thanks guys.

Re: Multiple file extensions in ExamineDirectory() ?

Posted: Mon Feb 21, 2011 6:27 pm
by Rook Zimbabwe
sorry Ideasvacuum... I had to recode original posting... hope the clarified code worked! :mrgreen:

Re: Multiple file extensions in ExamineDirectory() ?

Posted: Mon Feb 21, 2011 6:51 pm
by IdeasVacuum
Works very well Rook, with no perceivable lag time for my purposes. Funny how Kenmo brought up the subject just as I needed to find a solution. It would be nice if a multi-pattern could be used of course, since you should then end-up with a list of files in the same order as in Windows, without a subsequent sort of your own.

Re: Multiple file extensions in ExamineDirectory() ?

Posted: Mon Feb 21, 2011 8:15 pm
by TerryHough
Why couldn't you work something like

Code: Select all

SetCurrentDirectory("C:\folder\")
Type.l = #PB_Explorer_AutoSort | #PB_Explorer_NoFolders | #PB_Explorer_NoParentFolder | #PB_Explorer_NoDirectoryChange                 
ExplorerListGadget(0, 10, 10, 380, 180,  GetCurrentDirectory() + "*.dll;*.exe;*.com",  Type)
into the ExamineDirectory() recursion? Then you just process the files in that list.

Re: Multiple file extensions in ExamineDirectory() ?

Posted: Mon Feb 21, 2011 9:38 pm
by C64
Rook's solution is far too slow for large directories, slow devices (DVD drives) and low-bandwidth network shares; because it basically does a whole directory scan for each extension required. You should only do one single directory scan, and check the extension for each file found during the scan. Kenmo's solution is MUCH faster.

Re: Multiple file extensions in ExamineDirectory() ?

Posted: Mon Feb 21, 2011 10:06 pm
by Rook Zimbabwe
yep... but I wasn't looking for speed... I like Terrys idea though... and you don't have to scan for *. cause that would ONLY show folders (directories!) :mrgreen: nor the *.* but if you wanted to scan for SPECIFIC file types... like say *.txt and *.rtf and used terry's ignore codes... it might be fast enough to be a moot point! :mrgreen:

Re: Multiple file extensions in ExamineDirectory() ?

Posted: Mon Feb 21, 2011 11:20 pm
by TerryHough
Actually, thanks to idle, we already have the solution.

Look here.
http://www.purebasic.fr/english/viewtop ... +directory

Code needs a slight update to run under PB 4.51

Code: Select all

Procedure Findfiles(*fn,StartDirectory.s,pattern.s,Recursive=1)
  Static strFiles.s,ct1,ptc,bPattern
  
  Protected k,ct 
  If Not bPattern 
    tpattern.s = RemoveString(pattern,"*")
    ptc = CountString(tpattern,"|")
    Static Dim pt.s(20)
    For k=1 To ptc+1
      pt(k-1) = StringField(tpattern,k,"|")
      Debug pt(k-1)
    Next
    bPattern = #True 
  EndIf 
  
  mDir = ExamineDirectory(#PB_Any, StartDirectory, "*.*") 
  If mDir 
    While NextDirectoryEntry(mDir)
      If DirectoryEntryType(mDir) = #PB_DirectoryEntry_File
        Directory$ = StartDirectory
        FileName.s = DirectoryEntryName(mDir)
        ct=0
        While ct <= ptc   
          If FindString(FileName,pt(ct), 1)
            FullFileName.s = StartDirectory + "\" + FileName
            If CallFunctionFast(*fn, @FullFileName) = 0 
              Break 2    
            EndIf    
            Ct1 + 1
          EndIf
          ct+1 
        Wend    
      Else
        tdir$ = DirectoryEntryName(mDir)
        If tdir$ <> "." And tdir$ <> ".."
          If Recursive = 1
            Findfiles(*fn,StartDirectory + "\" + tdir$,"")
          EndIf
        EndIf
      EndIf
    Wend
    FinishDirectory(mDir)
  EndIf
  
  ProcedureReturn ct1 
  
EndProcedure

Global NewList myfiles.s()
Global Msg$

Procedure MyCallBack(ResultString.s)
  Msg$ + ResultString + " "
  ProcedureReturn #True 
EndProcedure

count = FindFiles(@MyCallBack(),"C:\folder", "*.exe|*.dll|*.txt",1)

MessageRequester("Find Files", Msg$ + #LF$ + Str(count) + " files", #MB_ICONINFORMATION) 
NOTE: The above routine is case sensitive. For example: Program.EXE will not match *.exe. So, a code modification will be required.

Re: Multiple file extensions in ExamineDirectory() ?

Posted: Tue Feb 22, 2011 1:32 pm
by IdeasVacuum
...wow that is fast! :mrgreen:

Re: Multiple file extensions in ExamineDirectory() ?

Posted: Tue Feb 22, 2011 1:50 pm
by MachineCode
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)