Jump to content

_FileSearch using recursion


GaryFrost
 Share

Recommended Posts

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.

 

Link to comment
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.

 

Link to comment
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]

Link to comment
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.

Link to comment
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? :)
Link to comment
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

Link to comment
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
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...