Sign in to follow this  
Followers 0
GaryFrost

_FileSearch using recursion

15 posts in this topic

#1 ·  Posted (edited)

Wild cards are accepted

suggestions/comments/bug reports are gladly welcome.

Examples of search:

dim $a_foundfiles = _FileSearch(@ProgramFilesDir & "\AutoIt3\Examples\GUI\Advanced","m*.au?")
if(Not IsArray($a_foundfiles)) Then
 MsgBox(0,"","file not found")
Else
 for $i=1 to $a_foundfiles[0]
    MsgBox(0,"Found",$a_foundfiles[$i])
 Next
EndIf

dim $a_foundfiles = _FileSearch(@ProgramFilesDir & "\AutoIt3\Examples","*.au3")
if(Not IsArray($a_foundfiles)) Then
 MsgBox(0,"","file not found")
Else
 for $i=1 to $a_foundfiles[0]
    MsgBox(0,"Found",$a_foundfiles[$i])
 Next
EndIf

Function code

Func _FileSearch($s_root,$s_filepattern)
; $s_root - where to start searching from
    Dim $s_troot = $s_root
    Dim $a_folders[1],$a_files[1],$attrib
    $a_folders[0] = 0
    $a_files[0] = 0
    $s_troot = StringReplace($s_troot,"/","\")
    If(Not (StringMid($s_troot,StringLen($s_troot),1) == "\")) Then
        $s_troot = $s_troot & "\"
    EndIf
; let's not be a cpu hog
    Sleep ( 10 )
; search the folder for all files and folders
    $search = FileFindFirstFile($s_troot & "*.*")
    
; Check if the search was successful
    If $search = -1 Then
         MsgBox(0, "Error", "No files/directories matched the search pattern")
         Exit
    EndIf
    
    While 1
        $file = FileFindNextFile($search)
        If @error Then ExitLoop
        if($file <> "." And $file <> "..") Then
            $attrib = FileGetAttrib($s_troot & $file)
        ; set folders for recursion search
            if(StringInStr($attrib,"D")) Then
                    ReDim $a_folders[$a_folders[0] + 2]
                    $a_folders[0] = $a_folders[0] + 1
                    $a_folders[$a_folders[0]] = $file
            Else
            ; wild cards accepted
            ; only wild cards used
                if($s_filepattern == "*.*" Or $s_filepattern == "*") Then
                ; add to array
                    ReDim $a_files[$a_files[0] + 2]
                    $a_files[0] = $a_files[0] + 1
                    $a_files[$a_files[0]] = $s_troot & $file
                Else
                ; lets search with wild cards in the string
                    Dim $s_temp = $file
                ; take care of the left side if *. is used
                    If(StringInStr($s_filepattern,"*.")) Then
                        $s_temp = StringMid($s_temp,1,StringInStr($s_filepattern,"*.")-1) & "*." & StringMid($s_temp,StringInStr($s_temp,".",0,-1)+1)
                    EndIf
                ; take care of any ?
                    $x = 1
                    while $x
                        if(StringInStr($s_filepattern,"?",0,$x)) Then
                            $s_temp = StringReplace($s_temp,StringInStr($s_filepattern,"?",0,$x),"?",1)
                            $x = $x + 1
                        Else
                            $x = 0
                        EndIf
                    WEnd
                ; take care of right side if .* is used
                    If(StringMid($s_filepattern,StringLen($s_filepattern) - 1,2) = ".*") Then
                        $s_temp = StringReplace($s_temp,StringMid($s_temp,StringInStr($s_temp,".",0,-1)),".*",1)
                    EndIf
                ; if file matches the search file, then add to array
                    If(StringUpper($s_temp) == StringUpper($s_filepattern)) Then
                        ReDim $a_files[$a_files[0] + 2]
                        $a_files[0] = $a_files[0] + 1
                        $a_files[$a_files[0]] = $s_troot & $file
                    EndIf
                EndIf
            EndIf
        EndIf
    WEnd
; Close the search handle
    FileClose($search)
    
    dim $t_array
; found folders, let's search them also
    for $i=1 to $a_folders[0]
        $t_array = _FileSearch($s_troot & $a_folders[$i],$s_filepattern)
        if(IsArray($t_array)) Then
            $x = $a_files[0]
            ReDim $a_files[$a_files[0] + $t_array[0] + 1]
            $a_files[0] = $a_files[0] + $t_array[0]
            for $y = 1 To $t_array[0]
                $a_files[$y + $x] = $t_array[$y]
            Next
        EndIf
    Next
; file found, return array listing of path\file listing
    if($a_files[0] > 0) Then
        Return $a_files
    Else
    ; no files found
        Return 0
    EndIf
EndFunc
Edited by gafrost

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites



fixed it so it works for searching for file(s)/folder(s)

Func _FileSearch($S_ROOT, $S_FILEPATTERN)
   Dim $SEARCH, $FILE, $I, $X, $Y
  ; $s_root - where to start searching from
   Dim $S_TROOT = $S_ROOT
   Dim $A_FOLDERS[1], $A_FILES[1], $ATTRIB
   Dim $T_ARRAY
   $A_FOLDERS[0] = 0
   $A_FILES[0] = 0
   $S_TROOT = StringReplace($S_TROOT, "/", "\")
   If (Not (StringMid($S_TROOT, StringLen($S_TROOT), 1) == "\")) Then
      $S_TROOT = $S_TROOT & "\"
   EndIf
  ; let's not be a cpu hog
   Sleep(10)
  ; search the folder for all files and folders
   $SEARCH = FileFindFirstFile($S_TROOT & "*.*")
  ; Check if the search was successful
   If $SEARCH = -1 Then
    ;~MsgBox(0, "Error", "No files/directories matched the search pattern")
      Return 0
   EndIf
   While 1
      $FILE = FileFindNextFile($SEARCH)
      If @error Then ExitLoop
      if ($FILE <> "." And $FILE <> "..") Then
         $ATTRIB = FileGetAttrib($S_TROOT & $FILE)
        ; set folders for recursion search
         if (StringInStr($ATTRIB, "D")) Then
            ReDim $A_FOLDERS[$A_FOLDERS[0] + 2]
            $A_FOLDERS[0] = $A_FOLDERS[0] + 1
            $A_FOLDERS[$A_FOLDERS[0]] = $FILE
            EndIf
        ; wild cards accepted
        ; only wild cards used
            if ($S_FILEPATTERN == "*.*" Or $S_FILEPATTERN == "*") Then
            ; add to array
                ReDim $A_FILES[$A_FILES[0] + 2]
                $A_FILES[0] = $A_FILES[0] + 1
                $A_FILES[$A_FILES[0]] = $S_TROOT & $FILE
            Else
            ; lets search with wild cards in the string
                Dim $S_TEMP = $FILE
            ; take care of the left side if *. is used
                If (StringInStr($S_FILEPATTERN, "*.")) Then
                    $S_TEMP = StringMid($S_TEMP, 1, StringInStr($S_FILEPATTERN, "*.") - 1) & "*." & StringMid($S_TEMP, StringInStr($S_TEMP, ".", 0, -1) + 1)
                EndIf
            ; take care of any ?
                $X = 1
                While $X
                    if (StringInStr($S_FILEPATTERN, "?", 0, $X)) Then
                        $S_TEMP = StringReplace($S_TEMP, StringInStr($S_FILEPATTERN, "?", 0, $X), "?", 1)
                        $X = $X + 1
                    Else
                        $X = 0
                    EndIf
                WEnd
            ; take care of right side if .* is used
                If (StringMid($S_FILEPATTERN, StringLen($S_FILEPATTERN) - 1, 2) = ".*") Then
                    $S_TEMP = StringReplace($S_TEMP, StringMid($S_TEMP, StringInStr($S_TEMP, ".", 0, -1)), ".*", 1)
                EndIf
            ; if file matches the search file, then add to array
                If (StringUpper($S_TEMP) == StringUpper($S_FILEPATTERN)) Then
                    ReDim $A_FILES[$A_FILES[0] + 2]
                    $A_FILES[0] = $A_FILES[0] + 1
                    $A_FILES[$A_FILES[0]] = $S_TROOT & $FILE
                EndIf
            EndIf
      EndIf
   WEnd
  ; Close the search handle
   FileClose($SEARCH)
  ; found folders, let's search them also
   For $I = 1 To $A_FOLDERS[0]
      $T_ARRAY = _FileSearch($S_TROOT & $A_FOLDERS[$I], $S_FILEPATTERN)
      if (IsArray($T_ARRAY)) Then
         $X = $A_FILES[0]
         ReDim $A_FILES[$A_FILES[0] + $T_ARRAY[0] + 1]
         $A_FILES[0] = $A_FILES[0] + $T_ARRAY[0]
         For $Y = 1 To $T_ARRAY[0]
            $A_FILES[$Y + $X] = $T_ARRAY[$Y]
         Next
      EndIf
   Next
  ; file found, return array listing of path\file listing
   if ($A_FILES[0] > 0) Then
      Return $A_FILES
   Else
     ; no files found
      Return 0
   EndIf
EndFunc  ;==>_FileSearch

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites

thanks, not sure if there's a way around that one just yet.

I figured there would be a limit on it.


SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites

Didn't realize one was already out there, with the same name even.

Well it was fun messing with it anyways.


SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites

yup, ezzetabi made a _FileSearch too. I use his in my SearchBar script


[font="Times"] If anyone remembers me, I am back. Maybe to stay, maybe not.----------------------------------------------------------------------------------------------------------[/font][font="Times"]Things I am proud of: Pong! in AutoIt | SearchbarMy website: F.R.I.E.S.A little website that is trying to get started: http://thepiratelounge.net/ (not mine)[/font][font="Times"] ----------------------------------------------------------------------------------------------------------[/font][font="Arial"]The newbies need to stop stealing avatars!!! It is confusing!![/font]

Share this post


Link to post
Share on other sites

As an aside, is there any will to rummage through the forums and put together all the little snippets that are hidden in there? A search would be so cool.

I don't mean the forum search is bad, but if what you're really looking for is variants on filesearch code, for example, forum search can be tedious. It doesn't give you "the bottom line" per se.

I have reviewed the public file area and it is basically intimidating because you need to search by author. The UDF page is OK, but leaves out a ton of "best practices" that have been found by forum readers' trial and error.

Am I missing something obvious?

I will contribute to this cause; I recognize this is a big task.

Please let me know if I should recreate this post elsewhere.

J


If I am too verbose, just say so. You don't need to run on and on.

Share this post


Link to post
Share on other sites

As an aside, is there any will to rummage through the forums and put together all the little snippets that are hidden in there?  A search would be so cool.

I don't mean the forum search is bad, but if what you're really looking for is variants on filesearch code, for example, forum search can be tedious.  It doesn't give you "the bottom line" per se.

I have reviewed the public file area and it is basically intimidating because you need to search by author.  The UDF page is OK, but leaves out a ton of "best practices" that have been found by forum readers' trial and error.

Am I missing something obvious?

I will contribute to this cause; I recognize this is a big task.

Please let me know if I should recreate this post elsewhere.

J

<{POST_SNAPBACK}>

The Autoit Wiki sounds good for the best UDFs? :)

Share this post


Link to post
Share on other sites

Do not know if your post has some hidden implication.

In five minutes time I could not find any such Autoit Wiki.

J


If I am too verbose, just say so. You don't need to run on and on.

Share this post


Link to post
Share on other sites

AutoItScript Wiki

<{POST_SNAPBACK}>

In the sample files of AutoIt v1.1.8 is also a FileSearchTest.au3 that uses COM.

Only a few lines of script, but it requires Microsoft Office to be installed on the computer.

-Sven

Share this post


Link to post
Share on other sites

yuck, trying to stay away from worring about other software installed to make a function work.


SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites

yuck, trying to stay away from worring about other software installed to make a function work.

<{POST_SNAPBACK}>

Oh well, I had to install this software package called 'Windows' before I could use your _FileSearch function.

:-)

-Sven

Share this post


Link to post
Share on other sites

I wrote 2 versions of pretty much the same thing, 1 similar to yours, and 1 using my Stack UDFs. In my tests the searchs were faster using my version w/ the Stack UDFs. Anywho heres a version w/ a gui:

Recursive.zip


Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs

Share this post


Link to post
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
Sign in to follow this  
Followers 0