Jump to content

Whats the Best/Fastest Recursive File Search Func..?


Recommended Posts

  • Moderators

cypher175,

This one developed by me from the _FileListToArray function:

#include-once

; #FUNCTION# ====================================================================================================

================
; Name...........: _RecFileListToArray
; Description ...: Lists files and\or folders in a specified path (Similar to using Dir with the /B Switch)
; Syntax.........: _RecFileListToArray($sPath[, $sFilter = "*"[, $iFlag = 0[, $iRecur = 0[, $iFullPath = 0]]]])
; Parameters ....: $sPath   - Path to generate filelist for.
;                 $sFilter - Optional the filter to use, default is *. Search the Autoit3 helpfile for the word "WildCards" For details.
;                 $iFlag   - Optional: specifies whether to return files folders or both
;                 |$iFlag=0 (Default) Return both files and folders
;                 |$iFlag=1 Return files only
;                 |$iFlag=2 Return Folders only
;                 $iRecur  - Optional: specifies whether to search in subfolders
;                 |$iRecur=0 (Default) Do not search in subfolders
;                 |$iRecur=1 Search in subfolders
;                 $iFullPath  - Optional: specifies whether to include initial path in result string
;                 |$iFullPath=0 (Default) Do not include initial path
;                 |$iFullPath=1 Include initial path
; Return values .: @Error - 1 = Path not found or invalid
;                 |2 = Invalid $sFilter
;                 |3 = Invalid $iFlag
;                 |4 = Invalid $iRecur
;                 |5 = Invalid $iFullPath
;                 |6 = No File/Folder Found
; Author ........: SolidSnake <MetalGX91 at GMail dot com>
; Modified.......: 22 Jan 09 by Melba23 - added recursive search and full path options
; Remarks .......: The array returned is one-dimensional and is made up as follows:
;                               $array[0] = Number of Files\Folders returned
;                               $array[1] = 1st File\Folder
;                               $array[2] = 2nd File\Folder
;                               $array[3] = 3rd File\Folder
;                               $array[n] = nth File\Folder
; Related .......:
; Link ..........;
; Example .......; Yes
; ====================================================================================================

===========================
;Special Thanks to Helge and Layer for help with the $iFlag update
; speed optimization by code65536
;===============================================================================
Func _RecFileListToArray($sPath, $sFilter = "*", $iFlag = 0, $iRecur = 0, $iFullPath = 0)
    Local $asFileList[1], $sFullPath
    If Not FileExists($sPath) Then Return SetError(1, 1, "")
    If StringRight($sPath, 1) <> "\" Then $sPath = $sPath & "\"
    If (StringInStr($sFilter, "\")) Or (StringInStr($sFilter, "/")) Or (StringInStr($sFilter, ":")) Or (StringInStr($sFilter, ">")) Or (StringInStr($sFilter, "<")) Or (StringInStr($sFilter, "|")) Or (StringStripWS($sFilter, 8) = "") Then Return SetError(2, 2, "")
    If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(3, 3, "")
    If Not ($iRecur = 0 Or $iRecur = 1) Then Return SetError(4, 4, "")
    If $iFullPath = 0 Then
        $sFullPath = $sPath
    ElseIf $iFullPath = 1 Then
        $sFullPath = ""
    Else
        Return SetError(5, 5, "")
    EndIf
    _FLTA_Search($sPath, $sFilter, $iFlag, $iRecur, $sFullPath, $asFileList)
    If $asFileList[0] = 0 Then Return SetError(6, 6, "")
    Return $asFileList
EndFunc  ;==>_FileListToArray

; #INTERNAL_USE_ONLY#=================================================================================

===========================
; Name...........: _FLTA_Search
; Description ...: Searches folder for files and then recursively searches in subfolders
; Syntax.........: _FLTA_Search($sStartFolder, $sFilter, $iFlag, $iRecur, $sFullPath, ByRef $asFileList)
; Parameters ....: $sStartFolder - Value passed on from UBound($avArray)
;                 $sFilter - As set in _FileListToArray
;                 $iFlag - As set in _FileListToArray
;                 $iRecur - As set in _FileListToArray
;                 $sFullPath - $sPath as set in _FileListToArray
;                 $asFileList - Array containing found files/folders 
; Return values .: None
; Author ........: Melba23 based on code from _FileListToArray by SolidSnake <MetalGX91 at GMail dot com>
; Modified.......: 
; Remarks .......: This function is used internally by _FileListToArray.
; Related .......:
; Link ..........; 
; Example .......;
; ====================================================================================================

===========================
Func _FLTA_Search($sStartFolder, $sFilter, $iFlag, $iRecur, $sFullPath, ByRef $asFileList)
    
    Local $hSearch, $sFile

    If StringRight($sStartFolder, 1) <> "\" Then $sStartFolder = $sStartFolder & "\"
; First look for filtered files/folders in folder
    $hSearch = FileFindFirstFile($sStartFolder & $sFilter)
    If $hSearch > 0 Then
        While 1
            $sFile = FileFindNextFile($hSearch)
            If @error Then ExitLoop
            Switch $iFlag
                Case 0; Both files and folders
                    If $iRecur And StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") <> 0 Then ContinueLoop
                Case 1; Files Only
                    If StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") <> 0 Then ContinueLoop
                Case 2; Folders only
                    If StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") = 0 Then ContinueLoop
            EndSwitch
            If $iFlag = 1 And StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") <> 0 Then ContinueLoop
            If $iFlag = 2 And StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") = 0 Then ContinueLoop
            _FLTA_Add($asFileList, $sFullPath, $sStartFolder, $sFile)
        WEnd
        FileClose($hSearch)
        ReDim $asFileList[$asFileList[0] + 1]
    EndIf
    
    If $iRecur = 1 Then
    ; Now look for subfolders
        $hSearch = FileFindFirstFile($sStartFolder & "*.*")
        If $hSearch > 0 Then
            While 1
                $sFile = FileFindNextFile($hSearch)
                If @error Then ExitLoop
                If StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") And ($sFile <> "." Or $sFile <> "..") Then
                ; If folders needed, add subfolder to array
                    If $iFlag <> 1 Then _FLTA_Add($asFileList, $sFullPath, $sStartFolder, $sFile)
                ; Recursive search of this subfolder
                    _FLTA_Search($sStartFolder & $sFile, $sFilter, $iFlag, $iRecur, $sFullPath, $asFileList)
                EndIf
            WEnd
            FileClose($hSearch)
        EndIf
    EndIf
    
EndFunc

; #INTERNAL_USE_ONLY#=================================================================================

===========================
; Name...........: _FLTA_Add
; Description ...: Searches folder for files and then recursively searches in subfolders
; Syntax.........: _FLTA_Add(ByRef $asFileList, $sFullPath, $sStartFolder, $sFile)
; Parameters ....: $asFileList - Array containing found files/folders 
;                 $sFullPath - $sPath as set in _FileListToArray
;                 $sStartFolder - Value passed on from UBound($avArray)
;                 $sFile - Full path of file/folder to add to $asFileList
; Return values .: Function only changes $asFileList ByRef
; Author ........: Melba23 based on code from _FileListToArray by SolidSnake <MetalGX91 at GMail dot com>
; Modified.......: 
; Remarks .......: This function is used internally by _FileListToArray.
; Related .......:
; Link ..........; 
; Example .......;
; ====================================================================================================

===========================
Func _FLTA_Add(ByRef $asFileList, $sFullPath, $sStartFolder, $sFile)
    
    Local $sAddFolder
    
    $asFileList[0] += 1
    If UBound($asFileList) <= $asFileList[0] Then ReDim $asFileList[UBound($asFileList) * 2]
    If $sFullPath = "" Then
        $sAddFolder = $sStartFolder
    Else
        $sAddFolder = StringReplace($sStartFolder, $sFullPath, "")
    EndIf
    $asFileList[$asFileList[0]] = $sAddFolder & $sFile
    
EndFunc

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

To get first the handle of the "first" file on the drive using FileFindFirstFile (first change to working directory to the drive like "C:\") and then preform FileFindNextFile in addition to FileGetAttrib to determine if a given handle is a directory or not. Don't forget to skip two files always which are '.' and '..' which every directory has.

Edit: On each step of the recursion you'll need to change the working directory depending on the last recursion if you're now working on a sub directory.

Edited by Authenticity
Link to comment
Share on other sites

I like this one the best. I forget who made it... I think weapon x but can't be sure.

Func RecursiveFileSearch($RFSstartDir, $RFSFilepattern = ".", $RFSFolderpattern = ".", $RFSFlag = 0, $RFSrecurse = true, $RFSdepth = 0)
    
   ;Ensure starting folder has a trailing slash
     If StringRight($RFSstartDir, 1) <> "\" Then $RFSstartDir &= "\"

     If $RFSdepth = 0 Then
       ;Get count of all files in subfolders for initial array definition
         $RFSfilecount = DirGetSize($RFSstartDir, 1)
        
       ;File count + folder count (will be resized when the function returns)
        If IsArray($RFSfilecount) Then 
            Global $RFSarray[$RFSfilecount[1] + $RFSfilecount[2] + 1]
        Else
            SetError(1)
            Return
        EndIf
     EndIf
    
     $RFSsearch = FileFindFirstFile($RFSstartDir & "*.*")
     If @error Then Return

   ;Search through all files and folders in directory
     While 1
         $RFSnext = FileFindNextFile($RFSsearch)
         If @error Then ExitLoop
        
       ;If folder and recurse flag is set and regex matches
         If StringInStr(FileGetAttrib($RFSstartDir & $RFSnext), "D") Then
            
             If $RFSrecurse AND StringRegExp($RFSnext, $RFSFolderpattern, 0) Then
                 RecursiveFileSearch($RFSstartDir & $RFSnext, $RFSFilepattern, $RFSFolderpattern, $RFSFlag, $RFSrecurse, $RFSdepth + 1)
                 If $RFSFlag <> 1 Then
                   ;Append folder name to array
                     $RFSarray[$RFSarray[0] + 1] = $RFSstartDir & $RFSnext
                     $RFSarray[0] += 1
                 EndIf
             EndIf
         ElseIf StringRegExp($RFSnext, $RFSFilepattern, 0) AND $RFSFlag <> 2 Then
           ;Append file name to array
             $RFSarray[$RFSarray[0] + 1] = $RFSstartDir & $RFSnext
             $RFSarray[0] += 1
         EndIf
     WEnd
     FileClose($RFSsearch)

     If $RFSdepth = 0 Then
         Redim $RFSarray[$RFSarray[0] + 1]
         Return $RFSarray
     EndIf
EndFunc ;==>RecursiveFileSearch
Link to comment
Share on other sites

  • Moderators

well which ones is the most widely supported & used here that works the best..??

Could probably have found what you were looking for, and the answer to your other question with less effort than it took to start or reply to this thread :) ...

http://www.autoitscript.com/forum/index.ph...ileListToArray*

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...