blindwig Posted June 4, 2005 Share Posted June 4, 2005 I started out writing a UDF that would return a list of all files in a specified folder, in an array that could be handled by the Array standard UDF. Then, I wanted to specify a mask to match. Easy enough. Then, I wanted to filter the files by their attributes - for example, only return files (not folders) or don't return hidden files, or only return archive-flagged files, etc. So, first I started by writing a file-filter routine, that takes a file and a filter string and returns true or false based on weather the file matches the filter: Func _FileFilterAttrib($FileName, $Attrib) Dim $Return=0, $FileAttrib, $i, $ch If FileExists($FileName) Then $Return=-1 $FileAttrib = FileGetAttrib($FileName) For $i = 1 to StringLen($Attrib) $ch = StringMid($Attrib,$i,1) If StringIsUpper($ch) Then ;This attribute must be on the list If not StringInStr($FileAttrib, $ch) then $Return = 0 Else ;This attribute must not be on the list If StringInStr($FileAttrib, StringUpper($ch)) then $Return = 0 EndIf Next EndIf Return $Return EndFunc The way the filter works is this: It is a string of characters, the same of which are returned by the function FileGetAttribute If a character is uppercase, then the file MUST hast this attribute to pass the filter, and if the character is lower-case then the file must NOT have this attribute to pass the filter. For example, the default filter 'dhs' will only return true on files that are not directory, hidden, or system flagged. The filter 'D' would only return directories, and the filter 'Dh' would return directories that are not hidden. The next step is to wrap this in a file searching routine, that would search an entire folder, first matching based on a filename mask, then filter by attributes: Func _FileFindAll($Path, $Mask="*", $AttribFilter='dhs') Dim $FileList[100], $FileListSize = 0, $hndFile_Search, $CurFile If FileIsDir($Path) Then;Path exists and is a directory $hndFile_Search = FileFindFirstFile($Path & '\' & $Mask) If $hndFile_Search<>-1 Then; at least 1 file/directory exists $CurFile = FileFindNextFile($hndFile_Search) While not @error;loop through found files If FileFilterAttrib($Path & '\' & $CurFile, $AttribFilter) Then;file passes attribute filter $FileListSize = $FileListSize + 1 If $FileListSize > UBound($FileList) Then ReDim $FileList[$FileListSize+20];increase list size $FileList[$FileListSize - 1] = $CurFile EndIf $CurFile = FileFindNextFile($hndFile_Search) WEnd FileClose($hndFile_Search) ReDim $FileList[$FileListSize] Return $FileList EndIf EndIf Return 0 EndFunc Calling it is pretty self-explanitory, I think: _FileFindAll('C:\Windows','*.exe','dhs') returns an array where [0]=number of results, and [1]...[x] are the file names. My UDF Threads:Pseudo-Hash: Binary Trees, Flat TablesFiles: Filter by Attribute, Tree List, Recursive Find, Recursive Folders Size, exported to XMLArrays: Nested, Pull Common Elements, Display 2dSystem: Expand Environment Strings, List Drives, List USB DrivesMisc: Multi-Layer Progress Bars, Binary FlagsStrings: Find Char(s) in String, Find String in SetOther UDF Threads I Participated:Base64 Conversions Link to comment Share on other sites More sharing options...
FuryCell Posted June 5, 2005 Share Posted June 5, 2005 (edited) I started out writing a UDF that would return a list of all files in a specified folder, in an array that could be handled by the Array standard UDF. Then, I wanted to specify a mask to match. Easy enough. Then, I wanted to filter the files by their attributes - for example, only return files (not folders) or don't return hidden files, or only return archive-flagged files, etc.So, first I started by writing a file-filter routine, that takes a file and a filter string and returns true or false based on weather the file matches the filter:Func _FileFilterAttrib($FileName, $Attrib) Dim $Return=0, $FileAttrib, $i, $ch If FileExists($FileName) Then $Return=-1 $FileAttrib = FileGetAttrib($FileName) For $i = 1 to StringLen($Attrib) $ch = StringMid($Attrib,$i,1) If StringIsUpper($ch) Then ;This attribute must be on the list If not StringInStr($FileAttrib, $ch) then $Return = 0 Else ;This attribute must not be on the list If StringInStr($FileAttrib, StringUpper($ch)) then $Return = 0 EndIf Next EndIf Return $Return EndFuncThe way the filter works is this:It is a string of characters, the same of which are returned by the function FileGetAttributeIf a character is uppercase, then the file MUST hast this attribute to pass the filter, and if the character is lower-case then the file must NOT have this attribute to pass the filter.For example, the default filter 'dhs' will only return true on files that are not directory, hidden, or system flagged. The filter 'D' would only return directories, and the filter 'Dh' would return directories that are not hidden.The next step is to wrap this in a file searching routine, that would search an entire folder, first matching based on a filename mask, then filter by attributes:Func _FileFindAll($Path, $Mask="*", $AttribFilter='dhs') Dim $FileList[100], $FileListSize = 0, $hndFile_Search, $CurFile If FileIsDir($Path) Then;Path exists and is a directory $hndFile_Search = FileFindFirstFile($Path & '\' & $Mask) If $hndFile_Search<>-1 Then; at least 1 file/directory exists $CurFile = FileFindNextFile($hndFile_Search) While not @error;loop through found files If FileFilterAttrib($Path & '\' & $CurFile, $AttribFilter) Then;file passes attribute filter $FileListSize = $FileListSize + 1 If $FileListSize > UBound($FileList) Then ReDim $FileList[$FileListSize+20];increase list size $FileList[$FileListSize - 1] = $CurFile EndIf $CurFile = FileFindNextFile($hndFile_Search) WEnd FileClose($hndFile_Search) ReDim $FileList[$FileListSize] Return $FileList EndIf EndIf Return 0 EndFuncCalling it is pretty self-explanitory, I think:_FileFindAll('C:\Windows','*.exe','dhs')returns an array where [0]=number of results, and [1]...[x] are the file names.<{POST_SNAPBACK}>Cool! These are very handy functions to have around. Thanks. -SolidSnake Edited June 5, 2005 by SolidSnake HKTunes:Softpedia | GoogleCodeLyricToy:Softpedia | GoogleCodeRCTunes:Softpedia | GoogleCodeMichtaToolsProgrammer n. - An ingenious device that turns caffeine into code. Link to comment Share on other sites More sharing options...
busysignal Posted July 25, 2005 Share Posted July 25, 2005 It is pretty sad that I just found this post. Nice functions Blindwig.. I will have to add them to my listing of UDFs. Cheers.. Link to comment Share on other sites More sharing options...
blindwig Posted July 25, 2005 Author Share Posted July 25, 2005 See also my _FileFindAllR() function, which uses the same principal and also searches recursively:http://www.autoitscript.com/forum/index.php?showtopic=12835Since that post I have come up with a better progress bar for the _FileGetTreeList() function - the one in that function is random because I couldn't think of a way to make a progress bar for an unknown number of items - but the code is not very portable as is. I had planned to re-write it and post it here, but have had other projects to work on and haven't had a chance to come back to it. It uses a recursive guessing method that doesn't always work out right (proportionally speaking) but is a lot better than just throwing random numbers out to try to make it look like I'm doing something useful My UDF Threads:Pseudo-Hash: Binary Trees, Flat TablesFiles: Filter by Attribute, Tree List, Recursive Find, Recursive Folders Size, exported to XMLArrays: Nested, Pull Common Elements, Display 2dSystem: Expand Environment Strings, List Drives, List USB DrivesMisc: Multi-Layer Progress Bars, Binary FlagsStrings: Find Char(s) in String, Find String in SetOther UDF Threads I Participated:Base64 Conversions Link to comment Share on other sites More sharing options...
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