Jump to content

A faster _FileSearch()


sshrum
 Share

Recommended Posts

This func uses DOS (and the STDOUT) to do the work of file list retrieval. Works faster than Larry's version but especially noticable if you're getting back a lot of files.

This func is a direct replacment and is called in exactly the same fashion as Larry's version.

In it's current state, this func only returns filenames...you can mod it to return folder names as well or only by adjusting $sArguments which are DOS 'DIR' based ('dir /?' for help).

Func _FileSearch($sQuery, $iSubdir=0)
    $iLine = 0
    $sLine = ""
    $aLine = ""
    Dim $aFiles[100000]
    $aFiles[0] = 0
    $sArguments = "/a-d /b /on"
    If $iSubDir Then $sArguments = $sArguments & " /s"
    $aRaw = Run(@ComSpec & ' /c dir "' & $sQuery & '" ' & $sArguments, @SystemDir, @SW_HIDE, $STDOUT_CHILD)
    While 1
        $sLine = StdoutRead($aRaw)
        If @error Then ExitLoop
        $aLine = StringSplit($SLine, @CRLF)
        If $aLine[0] > 1 Then
            For $i = 1 To $aLine[0] - 1
                If $aLine[$i] = "" Then Continueloop
                $iLine = $iLine + 1
                $aFiles[$iLine] = $aLine[$i]
            Next
        ElseIf $aLine[0] = 1 Then
            If $aLine[1] = "" Then Continueloop
            If $aLine[1] = "File Not Found" Then Exitloop
            $iLine = $iLine + 1
            $aFiles[$iLine] = $aLine[1]
        Else
            ExitLoop
        EndIf
    Wend
    $aFiles[0] = $iLine
    ReDim $aFiles[$iLine + 1]
    Return $aFiles
EndFunc

Enjoy!

Edited by sshrum

Sean Shrum :: http://www.shrum.net

All my published AU3-based apps and utilities

'Make it idiot-proof, and someone will make a better idiot'

 

Link to comment
Share on other sites

Here's a revision where you can define the path, the query condition, and the DIR arguments you want to get back any sort of listing. Please note that the func syntax is different than the code snippet above.

Returns an array where $aFiles[0] = 0 if no files/dirs found

Func _FileSearch($sPath, $sQuery="*.*", $sArguments="/a-d")
; Sample arguments
; file list of 1 folder: '/a-d'
; file list of 1 folder and subfoldered files: '/a-d /s'
; directory list (no filenames): '/ad'
    $iLine = 0
    $sLine = ""
    $aLine = ""
    Dim $aFiles[100000]
    $aFiles[0] = 0
    $sArguments = $sArguments & " /b"
    $aRaw = Run(@ComSpec & ' /c dir "' & $sPath & '\' & $sQuery & '" ' & $sArguments, @SystemDir, @SW_HIDE, $STDOUT_CHILD)
    While 1
        $sLine = StdoutRead($aRaw)
        If @error Then ExitLoop
        $aLine = StringSplit($SLine, @CRLF)
        If $aLine[0] > 1 Then
            For $i = 1 To $aLine[0] - 1
                If $aLine[$i] = "" Then Continueloop
                If $aLine[$i] = "File Not Found" Then Exitloop
                $iLine = $iLine + 1
                $aFiles[$iLine] = $aLine[$i]
            Next
        ElseIf $aLine[0] = 1 Then
            If $aLine[1] = "" Then Continueloop
            If $aLine[1] = "File Not Found" Then Exitloop
            $iLine = $iLine + 1
            $aFiles[$iLine] = $aLine[1]
        Else
            ExitLoop
        EndIf
    Wend
    $aFiles[0] = $iLine
    ReDim $aFiles[$iLine + 1]
    Return $aFiles
EndFunc
Edited by sshrum

Sean Shrum :: http://www.shrum.net

All my published AU3-based apps and utilities

'Make it idiot-proof, and someone will make a better idiot'

 

Link to comment
Share on other sites

Nah.

I got the idea when I saw someone using the STDOUT for retrieving shell output. Figured I try it with DIR. Found out it was returning faster results then my then implemented Larry-version of _FileSearch.

Sean Shrum :: http://www.shrum.net

All my published AU3-based apps and utilities

'Make it idiot-proof, and someone will make a better idiot'

 

Link to comment
Share on other sites

  • Moderators

Nah.

I got the idea when I saw someone using the STDOUT for retrieving shell output. Figured I try it with DIR. Found out it was returning faster results then my then implemented Larry-version of _FileSearch.

I use this method (DOS) for all my FileReadToArray/Directory Recurse/FileSearch options myself, I don't use stdout though, I just let it write to a file, and do FileRead(), no time really lost there, and less chance of a screw up (and less CPU usage).

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • 3 months later...

any one have never implemented a filesearch function where i can give a "composite mask" (or query what ever u want to call ) as input?

ie i want to search all file *.exe and *.com and have back a single array of results

i need something that work like this:

$a = _FileSearch(mypath,"*.au3|*.au2",yeslooksubfoler)

how can i do?

no one never do something like?

thanks

Link to comment
Share on other sites

  • Moderators

any one have never implemented a filesearch function where i can give a "composite mask" (or query what ever u want to call ) as input?

ie i want to search all file *.exe and *.com and have back a single array of results

i need something that work like this:

$a = _FileSearch(mypath,"*.au3|*.au2",yeslooksubfoler)

how can i do?

no one never do something like?

thanks

_FileListToArrayEx

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

A note that the function is dependant upon #include <Constants.au3> would go a long way to making this friendly to use. :)

If you have no reason to #include the constants file then just change $STDOUT_CHILD to 2

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

  • 1 month later...

Great idea! I really like the thought of using the StdoutRead command. Ive always used code similar to do searches only i would export the search result to a .txt file.

RunWait(@ComSpec & ' /c dir "' & $sQuery & '"/a-d /b /on /s >C:\Searchresults.txt', @SystemDir, @SW_HIDE)
_FileReadToArray('C:\searchresults.txt', $aFiles)oÝ÷ Øbëay+]¢ëQy§[^­·jëø°j{^vÚr¥vÈhÂØ^ºÇ«¦º ­ë,jwp«HßÛÞ~§wbâ7ökj·!x¢g­)à²)¢ªí¢Ø^¢¸ v¥~)^±æ«r,k
h²×¢yrjZ-}«-z³§zØba¢è!!Ú'ßÛm)䶵ç²Úz)íçè®ËZµéÓ2½©nzÌ­ç()àº!¢»n²)යw-íéâ~'bvØ^±©r¦jwl©îjYr{ayÊ&©Ý¦º&¦ÒÊ©àyØ­ë-i¸­¶hém^v¸¯zÇ­È^±«­¢+ØÀÌØí±¥ÍÐô}¥±ÍÉ  ÌäíèÀäÈ쨹©Á¨í èÀäÈ쨹©Á¨íèÀäÈ쨹µÀ¨Ìäì°Ä¤)}ÉÉå¥ÍÁ±ä ÀÌØí±¥ÍаÌäíA¡½Ñ½ÌÌäì¤()Õ¹}¥±MÉ  ÀÌØíÍEÕÉä°ÀÌØí¥MÕ¥ÈôÀ¤(%¥´ÀÌØí¥±ÍlÅt(%¥´ÀÌØíÍ1¥¹°ÀÌØí1¥¹($ÀÌØí¥±ÍlÁtôÀ($ÀÌØíÍEÕÉäôMÑÉ¥¹MÁ±¥Ð ÀÌØíÍEÕÉä°ÌäììÌäì¤(%½ÈÀÌØí0ôÄQ¼ÀÌØíÍEÕÉålÁt($$ÀÌØíÍÉÕµ¹ÑÌôÅÕ½Ðì½µ½½½¸ÅÕ½Ðì($%%ÀÌØí¥MÕ¥ÈQ¡¸ÀÌØíÍÉÕµ¹ÑÌôÀÌØíÍÉÕµ¹Ñ̵ÀìÅÕ½Ðì½ÌÅÕ½Ðì($$ÀÌØíIÜôIÕ¸¡
½µMÁµÀìÌäì½¥ÈÅÕ½ÐìÌäìµÀìÀÌØíÍEÕÉålÀÌØí1tµÀìÌäìÅÕ½ÐìÌäìµÀìÀÌØíÍÉÕµ¹ÑÌ°MåÍѵ¥È°M]}!%°È¤($%]¡¥±Ä($$$ÀÌØíÍ1¥¹ôMѽÕÑI ÀÌØíIܤ($$%%ÉɽÈQ¡¸á¥Ñ1½½À($$$ÀÌØí1¥¹ôMÑÉ¥¹MÁ±¥Ð ÀÌØíÍ1¥¹°
I1¤($$%%ÀÌØí1¥¹lÁtÐìÄQ¡¸($$$%½ÈÀÌØí¤ôÄQ¼ÀÌØí1¥¹lÁt($$$$%%ÀÌØí1¥¹lÀÌØí¥tôÅÕ½ÐìÅÕ½ÐìQ¡¸
½¹Ñ¥¹Õ1½½À($$$$%I¥´ÀÌØí¥±ÍmU  ½Õ¹ ÀÌØí¥±Ì¤¬Åt($$$$$ÀÌØí¥±ÍmU  ½Õ¹ ÀÌØí¥±Ì¤´ÅtôÀÌØí1¥¹lÀÌØí¥t($$$%9áÐ($$%±Í%ÀÌØí1¥¹lÁtôÄQ¡¸($$$%%ÀÌØí1¥¹lÅtôÅÕ½ÐìÅÕ½ÐìQ¡¸
½¹Ñ¥¹Õ1½½À($$$%%ÀÌØí1¥¹lÅtôÅÕ½Ðí¥±9½Ð½Õ¹ÅÕ½ÐìQ¡¸á¥Ñ1½½À($$$%I¥´ÀÌØí¥±ÍmU ½Õ¹ ÀÌØí¥±Ì¤¬Åt($$$$ÀÌØí¥±ÍmU   ½Õ¹ ÀÌØí¥±Ì¤´ÅtôÀÌØí1¥¹lÅt($$%±Í($$$%á¥Ñ1½½À($$%¹%($%]¹(%9áÐ($ÀÌØí¥±ÍlÁtôU    ½Õ¹ ÀÌØí¥±Ì¤´Ä(%IÑÕɸÀÌØí¥±Ì)¹Õ¹
Link to comment
Share on other sites

Just wondering.. Is it possible to get the directory list (no filenames) of a directory AND subdirectories using your method? If it's possible, this could help me out a lot.

Thanks,

Kurt

Awaiting Diablo III..

Link to comment
Share on other sites

any one have never implemented a filesearch function where i can give a "composite mask" (or query what ever u want to call ) as input?

ie i want to search all file *.exe and *.com and have back a single array of results

i need something that work like this:

$a = _FileSearch(mypath,"*.au3|*.au2",yeslooksubfoler)

how can i do?

no one never do something like?

thanks

I like _FileSearch function from this forum:

Func _FileSearch($sIstr, $iSF)
 ; $iSF can sum up.
 ; $iSF = 4 means don't return also folders, only files.
 ; $iSF = 2 means stop at the first found.
 ; $iSF = 1 means looking in subfolders.
  
 ; An array is returned with the full path of all files found. The pos [0] keeps the number of elements.
  Local $sCriteria, $sBuffer, $iH, $iH2, $sCS, $sCF, $sCF2, $sCP, $sFP, $sOutPut = '', $aNull[1]
  $sCP = StringLeft($sIstr, StringInStr($sIstr, '\', 0, -1))
  If $sCP = '' Then $sCP = @WorkingDir & '\'
  $sCriteria = StringTrimLeft($sIstr, StringInStr($sIstr, '\', 0, -1))
  If $sCriteria = '' Then $sCriteria = '*.*'
  
 ;To begin we seek in the starting path.
  $sCS = FileFindFirstFile($sCP & $sCriteria)
  While $sCS <> - 1
     $sCF = FileFindNextFile($sCS)
     If @error Then
        FileClose($sCS)
        ExitLoop
     EndIf
     If $sCF = '.' Or $sCF = '..' Then ContinueLoop
     If Not (BitAND($iSF, 4) And StringInStr(FileGetAttrib($sCP & $sCF), 'd')) Then
        $sOutPut = $sOutPut & $sCP & $sCF & @LF
        If BitAND($iSF, 2) Then ExitLoop
     EndIf
  Wend
  
 ;And after, if needed, in the rest of the folders.
  If (BitAND($iSF, 2) Or BitAND($iSF, 3) And $sOutPut = '') Or (BitAND($iSF, 1) And Not BitAND($iSF, 2)) Then
     $sBuffer = @CR & $sCP & '*' & @LF;The buffer is set for keeping the given path plus a *.
     Do
        $sCS = StringTrimLeft(StringLeft($sBuffer, StringInStr($sBuffer, @LF, 0, 1) - 1), 1);current search.
        $sCP = StringLeft($sCS, StringInStr($sCS, '\', 0, -1));Current search path.
        $iH = FileFindFirstFile($sCS)
        While $iH <> - 1
           $sCF = FileFindNextFile($iH)
           If @error Then
              FileClose($iH)
              ExitLoop
           EndIf
           If $sCF = '.' Or $sCF = '..' Then ContinueLoop
           If StringInStr(FileGetAttrib($sCP & $sCF), 'd') Then
              $sBuffer = @CR & $sCP & $sCF & '\*' & @LF & $sBuffer;Every folder found is added in the begin of buffer
              $sFP = $sCP & $sCF & '\';                            for future search
              $iH2 = FileFindFirstFile($sFP & $sCriteria);         and checked with the criteria.
              While $iH2 <> - 1
                 $sCF2 = FileFindNextFile($iH2)
                 If @error Then
                    FileClose($iH2)
                    ExitLoop
                 EndIf
                 If $sCF2 = '.' Or $sCF2 = '..' Then ContinueLoop
                 If Not (BitAND($iSF, 4) And StringInStr(FileGetAttrib($sFP & $sCF2), 'd')) Then
                    $sOutPut = $sOutPut & $sFP & $sCF2 & @LF;Found items are put in the Output.
                    If BitAND($iSF, 2) Then
                       FileClose($iH2)
                       FileClose($iH)
                       ExitLoop 3
                    EndIf
                 EndIf
              Wend
           EndIf
        Wend
        $sBuffer = StringReplace($sBuffer, @CR & $sCS & @LF, '')
     Until $sBuffer = ''
  EndIf
  
  If $sOutPut = '' Then
     $aNull[0] = 0
     Return $aNull
  Else
     Return StringSplit(StringTrimRight($sOutPut, 1), @LF)
  EndIf
EndFunc  ;==>_FileSearch
oÝ÷ ØLZ^¡û¬y«­¢+ØÀÌØí¥±±¥ÍÐô}¥±MÉ  ÌäíèÀäÈí]½¹½ÝÌÀäÈ쨸¨Ìäì°Ä¬Ð¤)½ÈÀÌØí¤ôÄQ¼ÀÌØí¥±±¥ÍÑlÁt(ÀÌØí¥±}¹µôMÑÉ¥¹I¥¡Ð ÀÌØí¥±±¥ÍÑlÀÌØí¥t°MÑÉ¥¹1¸ ÀÌØí¥±±¥ÍÑlÀÌØí¥t¤´MÑÉ¥¹%¹MÑÈ ÀÌØí¥±±¥ÍÑlÀÌØí¥t°ÌäìÀäÈìÌäì°À°´Ä¤¤í½¹±ä¥±¹µÝ¥Ñ¡½ÕÐÁÑ (츸¸)9áÐ
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...