Jump to content

Some FileListToArray Example


Deye
 Share

Recommended Posts

This is My humble example for file listing with a Search term, The gui included allows to have a search term typed (used with wildCards * if needed) Right after Choosing a Drive, The other combo allows to select the directory depth level look ahead for a search (@counting from first on Root ) 

in no way this is to compete\compare any speed related .. with other versions of file listing, Just bookmarking this one for me to check later or for anyone wishing to take a peek on it ..

Spoiler
#include <File.au3>
#include <String.au3>
#include <GUIConstantsEx.au3>

$aArray = DriveGetDrive("ALL")
For $i = 1 To $aArray[0]
    $aArray[$i] = StringUpper($aArray[$i])
Next
$sString = _ArrayToString($aArray, "|", 1)

$hGUI = GUICreate("FileListLevel", 320, 125)
$hCombo = GUICtrlCreateCombo("", 10, 8, 44, 20)
GUICtrlSetFont(-1, 12)
GUICtrlSetData(-1, $sString)

$idFileInput = GUICtrlCreateInput("", 65, 8, 125, 25)
GUICtrlSetFont(-1, 12)

$hCombo2 = GUICtrlCreateCombo("SearchAllLevels", 10, 70, 180, 20)
GUICtrlSetFont(-1, 13)
GUICtrlSetData(-1, "1|2|3|4|5|6|7")

$Button = GUICtrlCreateButton("Search", 215, 08, 100, 25)
GUICtrlSetFont(-1, 12)
$ButtonCancel = GUICtrlCreateButton("Abort Search", 215, 45, 100, 25)
GUICtrlSetFont(-1, 12)
$ButtonResult = GUICtrlCreateButton("Copy result", 215, 80, 100, 25)
GUICtrlSetFont(-1, 12)

$File = GUICtrlCreateRadio("File", 10, 38, 50, 25)
GUICtrlSetFont(-1, 12)
GUICtrlSetState(-1, $GUI_CHECKED)
$Folder = GUICtrlCreateRadio("Folder", 65, 38, 70, 25)
GUICtrlSetFont(-1, 12)

$bBoth = GUICtrlCreateCheckbox("Both", 144, 40, 70)
GUICtrlSetFont(-1, 12)

Global $iCount, $aArray, $aResult, $sPattern, $sFilePath = @ScriptDir & "\TestUniqueResults1.txt", $bCancel = False

HotKeySet("{ESC}", "TerminateSearch")

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button
            $iLevel = GUICtrlRead($hCombo2)
            If BitAND(GUICtrlRead($bBoth), $GUI_CHECKED) Then
                $bFile = 2
            Else
                $bFile = BitAND(GUICtrlRead($File), $GUI_CHECKED) ? 1 : 0
            EndIf
            _Run(GUICtrlRead($hCombo) & GUICtrlRead($idFileInput), StringIsAlpha($iLevel) = 1 ? 0 : $iLevel, $bFile)
        Case $ButtonCancel
            $bCancel = True
        Case $ButtonResult
            _FileWriteFromArray($sFilePath, $aResult, 1)
    EndSwitch
WEnd
Func _gui()
    Switch GUIGetMsg()
        Case $ButtonCancel
            $bCancel = True
            AdlibUnRegister("_gui")
    EndSwitch
EndFunc   ;==>_gui

Func _Run($sSearchTerm, $iEndLevel, $bFile = 0)
    $bCancel = False
    ConsoleWrite("Level = " & $iEndLevel & @LF)
    Local $hTimer = TimerInit()

    $aResult = _Search($sSearchTerm, $iEndLevel, $bFile)
    ConsoleWrite("Time: " &TimerDiff($hTimer) & @LF)
    _ArrayDisplay($aResult, "Level " & $iEndLevel)
    ConsoleWrite("Done Searching" & @LF & @LF)
EndFunc   ;==>_Run

Func _Search($sSearch, $iEndLevel = 0, $bFile = 1)
    Dim $aArray[500]
    $iCount = 1
    Local $a = StringSplit($sSearch, ":"), $sPath

    $sPattern = "(?i)^" & StringReplace(StringRegExpReplace($a[2], "[][$^.{}()+\-]", "\\$0"), "*", ".*?") & "$"
    If $iEndLevel = 0 Then
        $sPath = $a[1] & ":\" & $a[2]
    Else
        $sPath = $a[1] & ":" & _StringRepeat("\*", $iEndLevel + 1)
        $sPath = StringTrimRight($sPath, 1) & $a[2]
    EndIf
    AdlibRegister("_gui", 50)
    _GetArray($iEndLevel, $bFile, $sPath)
    AdlibUnRegister("_gui")
    Local $iIndex = _ArraySearch($aArray, "", 1)
    Local $a = _ArrayExtract($aArray, 0, (@error = -1 ? UBound($aArray) : $iIndex - 1))
    $a[0] = UBound($a) - 1
    Return $a
EndFunc   ;==>_Search

Func _GetArray($iEndLevel, $bFile, $sPath, $iLevel = 0)

    Local $Item = StringSplit(StringRegExpReplace($sPath, '\\\Z', ''), '\')
    If $iEndLevel = 0 Then
    Else
        If $iLevel + 1 >= $Item[0] Then Return
    EndIf
    Local $hSearch, $File, $Suf, $Result

    For $i = 1 To $iLevel + 1
        $Result &= $Item[$i] & '\'
    Next
    $Result = StringRegExpReplace($Result, '\\\Z', '')

    If StringRegExp($Item[$iLevel + 1], $sPattern) Then
        If $iCount >= UBound($aArray) - 1 Then
            ReDim $aArray[UBound($aArray) * 2]
        EndIf
        $hSearch = FileFindFirstFile($Result & '\*')
        If $hSearch = -1 Or @error Then
            Switch $bFile
                Case 0
                    If @error Then
                        $aArray[$iCount] = $Result & "\"
                        $iCount += 1
                    EndIf
                Case 1, 2
                    $aArray[$iCount] = $Result
                    $iCount += 1
            EndSwitch
            Return
        ElseIf Not $bFile Or $bFile > 1 Then
            $aArray[$iCount] = $Result & "\"
            $iCount += 1
        EndIf
    Else
        $hSearch = FileFindFirstFile($Result & '\*')
        If $hSearch = -1 Then Return
    EndIf

    For $i = $iLevel + 3 To $Item[0]
        $Suf &= '\' & $Item[$i]
    Next

    While 1
        $File = FileFindNextFile($hSearch)
        If @error Then ExitLoop
        If (Not @extended) And ($iLevel + 2 = $Item[0]) Then
            ContinueLoop
        EndIf
        _GetArray($iEndLevel, $bFile, $Result & '\' & $File & $Suf & "\", $iLevel + 1)
        If $bCancel Then Return
    WEnd
    FileClose($hSearch)
EndFunc   ;==>_GetArray

Func TerminateSearch()
    $bCancel = True
EndFunc   ;==>TerminateSearch

 

sped up version:

Spoiler
#include <File.au3>
#include <String.au3>
#include <GUIConstantsEx.au3>

$aArray = DriveGetDrive("ALL")
For $i = 1 To $aArray[0]
    $aArray[$i] = StringUpper($aArray[$i])
Next
$sString = _ArrayToString($aArray, "|", 1)

$hGUI = GUICreate("FileListLevel", 320, 125)
$hCombo = GUICtrlCreateCombo("", 10, 8, 44, 20)
GUICtrlSetFont(-1, 12)
GUICtrlSetData(-1, $sString)

$idFileInput = GUICtrlCreateInput("", 65, 8, 125, 25)
GUICtrlSetFont(-1, 12)

$hCombo2 = GUICtrlCreateCombo("SearchAllLevels", 10, 70, 180, 20)
GUICtrlSetFont(-1, 13)
GUICtrlSetData(-1, "1|2|3|4|5|6|7")

$Button = GUICtrlCreateButton("Search", 215, 08, 100, 25)
GUICtrlSetFont(-1, 12)
$ButtonCancel = GUICtrlCreateButton("Abort Search", 215, 45, 100, 25)
GUICtrlSetFont(-1, 12)
$ButtonResult = GUICtrlCreateButton("Copy result", 215, 80, 100, 25)
GUICtrlSetFont(-1, 12)

$File = GUICtrlCreateRadio("File", 10, 38, 50, 25)
GUICtrlSetFont(-1, 12)
GUICtrlSetState(-1, $GUI_CHECKED)
$Folder = GUICtrlCreateRadio("Folder", 65, 38, 70, 25)
GUICtrlSetFont(-1, 12)

$bBoth = GUICtrlCreateCheckbox("Both", 144, 40, 70)
GUICtrlSetFont(-1, 12)

Global $iCount, $iTotalCount = 500, $aArray, $aResult, $sPattern, $sFilePath = @ScriptDir & "\TestUniqueResults1.txt", $bCancel = False

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button
            $iLevel = GUICtrlRead($hCombo2)
            If BitAND(GUICtrlRead($bBoth), $GUI_CHECKED) Then
                $bFile = 2
            Else
                $bFile = BitAND(GUICtrlRead($File), $GUI_CHECKED) ? 1 : 0
            EndIf
            _Run(GUICtrlRead($hCombo) & GUICtrlRead($idFileInput), StringIsAlpha($iLevel) = 1 ? 0 : $iLevel, $bFile)
        Case $ButtonCancel
            $bCancel = True
        Case $ButtonResult
            _FileWriteFromArray($sFilePath, $aResult, 1)
    EndSwitch
WEnd
Func _gui()
    Switch GUIGetMsg()
        Case $ButtonCancel
            $bCancel = True
            AdlibUnRegister("_gui")
    EndSwitch
EndFunc   ;==>_gui

Func _Run($sSearchTerm, $iEndLevel, $bFile = 0)
    $bCancel = False
    ConsoleWrite("Level = " & $iEndLevel & @LF)
    Local $hTimer = TimerInit()

    $aResult = _Search($sSearchTerm, $iEndLevel, $bFile)
    ConsoleWrite("Time: " & TimerDiff($hTimer) & @LF)
    _ArrayDisplay($aResult, "Level " & $iEndLevel)
    ConsoleWrite("Done Searching" & @LF & @LF)
EndFunc   ;==>_Run

Func _Search($sSearch, $iEndLevel = 0, $bFile = 1)
    Dim $aArray[$iTotalCount]
    $iCount = 1
    Local $a = StringSplit($sSearch, ":"), $sPath

    $sPattern = "(?i)^" & StringReplace(StringRegExpReplace($a[2], "[][$^.{}()+\-]", "\\$0"), "*", ".*?") & "$"

    AdlibRegister("_gui", 100)
    _GetArray($iEndLevel, $bFile, $a[1] & ":", "", $a[2])
    AdlibUnRegister("_gui")

    Local $iIndex = _ArraySearch($aArray, "", 1)
    Local $a = _ArrayExtract($aArray, 0, (@error = -1 ? UBound($aArray) : $iIndex - 1))
    $a[0] = UBound($a) - 1
    Return $a
EndFunc   ;==>_Search

Func _GetArray($iEndLevel, $bFile, $sPath, $File = "", $iLevel = 0)
    Local $hSearch, $Result = $sPath & $File
    If StringRegExp($File, $sPattern) Then
        If $iCount >= $iTotalCount - 1 Then
            $iTotalCount += $iTotalCount
            ReDim $aArray[$iTotalCount]
        EndIf
        $hSearch = FileFindFirstFile($Result & '\*')
        If $hSearch = -1 Then
            Switch $bFile
                Case 0
                    $aArray[$iCount] = $Result & "\"
                    $iCount += 1
                Case $bFile = @error
                Case Else
                    $aArray[$iCount] = $Result
                    $iCount += 1
            EndSwitch
            Return
        ElseIf Not $bFile Or $bFile > 1 Then
            $aArray[$iCount] = $Result & "\"
            $iCount += 1
        EndIf
        If $iEndLevel > 0 And $iLevel = $iEndLevel Then Return
    Else
        If $iEndLevel > 0 And $iLevel = $iEndLevel Then Return
        $hSearch = FileFindFirstFile($Result & '\*')
        If $hSearch = -1 Then Return
    EndIf

    While 1
        $File = FileFindNextFile($hSearch)
        If @error Then ExitLoop
        If (Not @extended) Then
            If Not $bFile Or Not StringRegExp($File, $sPattern) then ContinueLoop
        EndIf
        _GetArray($iEndLevel, $bFile, $Result & "\", $File, $iLevel + 1)
        If $bCancel Then Return
    WEnd
    FileClose($hSearch)
EndFunc   ;==>_GetArray

 

Deye

Edited by Deye
Link to comment
Share on other sites

11 hours ago, t0nZ said:

Tested. but I had to add 2 includes, files.au3 and array.au3.

sorry, missed the above line for the copy selection

11 hours ago, t0nZ said:

After the gui showed and selecting available drives, but how I insert the (partial?) name of the files to search ? 

Added in an input box for the search Term  (before you'd simply type along with the selected drive a search term  (NM No sweat ..)

Deye

Link to comment
Share on other sites

Thank you.

I learned a thing ! You gave me an idea ! Thank you !

The use of adlibregister/unregister to allow the user to stop a potentially too long process .

In my case I want to use this tecnique to pause hanging (S)FTP  connections.

Any advice about the right choice of milliseconds for Adlib ? You use 100ms I saw... so for you is always good choice  ??

Cheers !

Link to comment
Share on other sites

 you are welcome

1 hour ago, t0nZ said:

Any advice about the right choice of milliseconds for Adlib ? 

depends how fast you want the return to be in my example above anything higher then 150 will look like something got hanged

if you need it for some background process its best to keep at default = 250ms or higher so less resources your script will use

Link to comment
Share on other sites

Thank you @Deye for sharing your experience, my need is to stop a potentially hanged process (like an SFTP transfer when the other side is no more reachable, think about a remote user connected in hotspot in mobility with poor connection..).

I will do some trials...

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...