therks Posted November 29, 2011 Posted November 29, 2011 (edited) 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:#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 EndFuncexpandcollapse popup#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 EndFuncI'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 November 29, 2011 by therks My AutoIt Stuff | My Github
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now