Jump to content



Photo

Another recursive FileList function


  • Please log in to reply
1 reply to this topic

#1 therks

therks

    Witty quote

  • Active Members
  • PipPipPipPipPipPip
  • 2,163 posts

Posted 29 November 2011 - 06:27 AM

I know there's already several of these types of functions around the forum but there were some things I wanted to do different, so I wrote my own.
In the tests I've done this appears to be working fine, but I'd appreciate a second look.
The error returns and the first three parameters are the same as the vanilla _FileListToArray, but there are a couple new flags, and two new parameters.
The new flags include:
- enabling recursion (4)
- disabling file count in element [0] (8)
- enabling full path returns (16).
The new parameters are:
- $sCallback - this is the name of a function you want to run on each loop, it is passed an array with data relating to the current file search in the loop. If the callback function returns 0 then the item is processed normally. If it returns 1 the item is skipped (this can be used to skip entire folders being processed). If it returns -1 the entire function errors out with -1 and @extended is set to the callback function's @extended value.
- $sCallbackUserParam - just an extra parameter that can be passed through to the callback function.

Example with callback:
AutoIt         
#include <Array.au3> #include <_FileListToArrayRecursive.au3> Global $sWFile _FileListToArrayRecursive(@DesktopDir, '*', 4, '_Callback', 'Wfile') If @error = -1 And @extended = 42 Then     MsgBox(0, '', 'You have a W file:' & @LF & $sWFile) Else     MsgBox(0, '', 'No files/folders that start with W exist.') EndIf Global $aReadOnly = _FileListToArrayRecursive(@DesktopDir, '*', 1+4, '_Callback', 'readonly') Global $aEmpty = _FileListToArrayRecursive(@DesktopDir, '*', 1+4, '_Callback', 'empty') _ArrayDisplay($aReadOnly) _ArrayDisplay($aEmpty) Func _Callback($aParams)     Switch $aParams[5]         Case 'Wfile'             If StringLeft($aParams[2], 1) == 'W' Then                 $sWFile = $aParams[1] & $aParams[2]                 Return SetExtended(42, -1)             EndIf         Case 'empty'             If Not $aParams[3] Then                 If FileGetSize($aParams[0] & $aParams[1] & $aParams[2]) Then Return 1             EndIf         Case 'readonly'             If Not $aParams[3] Then                 If Not StringInStr(FileGetAttrib($aParams[0] & $aParams[1] & $aParams[2]), 'R') Then Return 1             EndIf     EndSwitch EndFunc


AutoIt         
#include-once ; #FUNCTION# ==================================================================================================================== ; Name...........: _FileListToArrayRecursive ; Description ...: Lists files and/or folders in a specified path recursively ; Syntax.........: _FileListToArrayRecursive($sPath[, $sFilter = '*'[, $iFlag = 0[, $sCallback = ''[, $sCallbackUserParam = '' ] ] ] ] ) ; Parameters ....: $sPath             - Path to search ;                 $sFilter          - Optional: the filter to use, default is * ;                 $iFlag              - Optional: specifies options about return, add flags together ;                 |$iFlag =  0 (Default) Return both files and folders ;                 |$iFlag =  1 Return files only ;                 |$iFlag =  2 Return folders only ;                 |$iFlag =  4 Search subfolders (Enable recursion) ;                 |$iFlag =  8 Make array 0-based (Disable return count in first element) ;                 |$iFlag = 16 Return full paths (default only returns from the search folder down) ;                 $sCallback          - Optional: function to call on each loop. See remarks for details (default: none) ;                 $sCallbackUserParam - Optional: a parameter to pass to the Callback function (default: none) ; Return values .: @Error - 1 = Path not found or invalid ;                 |2 = Invalid $sFilter ;                 |3 = Invalid $iFilter ;                 |4 = No files found or folder inaccessible ;                 |5 = No files found or folder inaccessible ;                 |-1 = Callback function returned -1 ; Author ........: Rob Saunders (therks at therks dot com) ; Modified.......: ; Remarks .......: If $sCallback is defined the function will be called on each loop and it can alter what files are recorded ;                 in the return array. The Callback function runs on every file result because it is called *before* the flag ;                 filter for files/folders ($iFlag 1 or 2). ;                   Return  0 = Item is added (depending on $iFlag 1 or 2) ;                   Return  1 = Item is skipped (note: if you skip a folder it will not be searched either) ;                   Return -1 = Stop searching. Main func returns false, @error = -1, @extended = Callback's @extended value ;                 The function is passed one parameter, a 6 item array with values as follows: ;                   [0] root search folder ;                   [1] current sub folder ;                   [2] current filename match ;                   [3] 1 if file is a folder; 0 if not ;                   [4] current file count ;                   [5] $sCallbackUserParam ; ; Related .......: _FileListToArray ; Link ..........: ; Example .......: ; Note ..........: Some parts from original function (by SolidSnake) and _FileListToArrayEx (by DXRW4E) ; =============================================================================================================================== Func _FileListToArrayRecursive($sPath, $sFilter = '*', $iFlag = 0, $sCallback = '', $sCallbackUserParam = '')     Local Const $FL_FILES = 1, $FL_FOLDERS = 2, $FL_RECURSE = 4, $FL_NOCOUNT = 8, $FL_FULLPATH = 16     If Not StringInStr(FileGetAttrib($sPath), 'D') Then Return SetError(1, 1, '')     If StringRegExp($sFilter, '[\\/:><\|]|(?s)\A\s*\z') Then Return SetError(2, 2, '')     If $iFlag < 0 Or $iFlag > 1+2+4+8+16 Then Return SetError(3, 3, '')     $sPath = StringRegExpReplace($sPath, '[\\/]+$', '') & '\'     Local $sFileTrack, $iFileCount, $hParentSearch, $hSearch, $hSubCheck, $sSubDir, $sFile, $iIsFolder, $sRegExFilter, $sAddFullPath, _         $iReturnFolders, $iReturnFiles, $iRecurse, $iReturnCount, $iSortOffset, _         $aCallbackData[6], $vCallbackReturn, $iCallbackExt     $aCallbackData[5] = $sCallbackUserParam     If BitAND($iFlag, $FL_FULLPATH) Then $sAddFullPath = $sPath     If BitAND($iFlag, $FL_RECURSE) Then         $iRecurse = 1         If StringReplace($sFilter, '*', '') Then ; If we ARE recursing, and the filter is something besides just * then initialize the regex filter             $sRegExFilter = '(?i)^' & StringRegExpReplace(StringReplace(StringRegExpReplace($sFilter, '(\.|\||\+|\(|\)|\{|\}|\[|\]|\^|\$|\\)', "\\$1"), '?', '.'), '\*+', '.*') & '$'             $sFilter = '*'         EndIf     EndIf     If BitAND($iFlag, $FL_FILES) Then         $iReturnFiles = 1     ElseIf BitAND($iFlag, $FL_FOLDERS) Then         $iReturnFolders = 1     Else         $iReturnFiles = 1         $iReturnFolders = 1     EndIf     If BitAND($iFlag, $FL_NOCOUNT) Then         $iReturnCount = 2 ; Param for StringSplit         $iSortOffset = 0     EndIf     $hParentSearch = FileFindFirstFile($sPath & $sSubDir & $sFilter)     If $hParentSearch = -1 Then Return SetError(4, 4, '')     $hSearch = $hParentSearch     While 1         $sFile = FileFindNextFile($hSearch)         If @error Then             If $hParentSearch = $hSearch Then ExitLoop             FileClose($hSearch)             $hSearch -= 1             $sSubDir = StringLeft($sSubDir, StringInStr(StringTrimRight($sSubDir, 1), '\', 0, -1))             ContinueLoop         EndIf         $iIsFolder = @extended         If $sCallback Then             $aCallbackData[0] = $sPath             $aCallbackData[1] = $sSubDir             $aCallbackData[2] = $sFile             $aCallbackData[3] = $iIsFolder             $aCallbackData[4] = $iFileCount             $vCallbackReturn = Call($sCallback, $aCallbackData)             If @error = 0xDEAD And @extended = 0xBEEF Then                 FileClose($hSearch)                 FileClose($hParentSearch)                 Return SetError(5, 5, '')             ElseIf $vCallbackReturn = -1 Then                 $iCallbackExt = @extended                 FileClose($hSearch)                 FileClose($hParentSearch)                 Return SetError(-1, $iCallbackExt, '')             ElseIf $vCallbackReturn Then                 ContinueLoop             EndIf         EndIf         If $iRecurse Then             If ($iIsFolder And $iReturnFolders) Or (Not $iIsFolder And $iReturnFiles) Then                 If Not $sRegExFilter Or ($sRegExFilter And StringRegExp($sFile, $sRegExFilter)) Then                     $sFileTrack &= '|' & $sAddFullPath & $sSubDir & $sFile                     $iFileCount += 1                 EndIf             EndIf             If $iIsFolder Then                 $hSubCheck = FileFindFirstFile($sPath & $sSubDir & $sFile & '\' & $sFilter)                 If $hSubCheck = -1 Then ContinueLoop                 $sSubDir &= $sFile & '\'                 $hSearch = $hSubCheck             EndIf         Else             If ($iIsFolder And $iReturnFolders) Or (Not $iIsFolder And $iReturnFiles) Then                 $sFileTrack &= '|' & $sAddFullPath & $sSubDir & $sFile                 $iFileCount += 1             EndIf         EndIf     WEnd     FileClose($hParentSearch)     Local $aReturnList = StringSplit(StringTrimLeft($sFileTrack, 1), '|', $iReturnCount)     If @error Then Return SetError(4, 4, '')     Return $aReturnList EndFunc


I'm still working on this as time goes by so the most up to date version can be found in my dropbox: http://db.tt/OqNgumLK

Edited by therks, 29 November 2011 - 06:41 AM.






#2 wliebkem

wliebkem

    Seeker

  • Active Members
  • 17 posts

Posted 24 December 2011 - 01:30 AM

Helpful - thanks!




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users