Jump to content

Looking for a way to reach the deepst folder


Recommended Posts

Hey guys,

Im looking for a way to look into the deepst folder, by deepst folder i mean, the folder that furthest down. Imagine you had a folder in a folder in a folder, 3 folders in total.

And u wanted a way to find the directory/handle of the 3rd folder. Is there a way to do this?

Thanks in advanced!

Link to comment
Share on other sites

check this

#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#include <File.au3>

_FindAllFile()

;----------------------------------------------------------------------------------------
Func _FindAllFile()
    Local $dir = @ScriptDir & "\kfc\"    ; <------------
    Local $ArraySrtfiles = _FileListToArrayRec($dir, "test*.txt", $FLTAR_FILES, $FLTAR_RECUR)
    If Not IsArray($ArraySrtfiles) Then
        ConsoleWrite($dir & " = Invalid input path" & @CRLF)
        Return
    Else
        For $x = 1 To $ArraySrtfiles[0]
            ;ConsoleWrite($dir & $ArraySrtfiles[$x]& @CRLF)
            _ReplaceTxt($dir & $ArraySrtfiles[$x])
        Next
    EndIf
EndFunc   ;==>_FindAllFile
;----------------------------------------------------------------------------------------
Func _ReplaceTxt($TxtFile)
    Local $sName = "\NewTest.txt"
    Local $NewTxtFile = @ScriptDir & $sName

    ;ReplaceTxt
    FileCopy($NewTxtFile, $TxtFile, $FC_OVERWRITE + $FC_CREATEPATH)

    Local $sFolder = StringLeft($TxtFile, StringInStr($TxtFile, "\", $STR_NOCASESENSEBASIC, -1) -1)

    ;FileRename
    FileMove($TxtFile, $sFolder & $sName, $FC_OVERWRITE + $FC_CREATEPATH)

EndFunc   ;==>_ReplaceTxt

you can see more here

https://www.autoitscript.com/forum/topic/209794-i-want-to-replace-files-in-folders-in-other-folders/

Edited by ioa747

I know that I know nothing

Link to comment
Share on other sites

or this :

#include <File.au3>

Local $aList = _FileListToArrayRec("c:\Apps", "*", $FLTAR_FOLDERS, $FLTAR_RECUR)
Local $iDeep = 0, $sFolder = ""
For $i = 1 To $aList[0]
  StringReplace($aList[$i], "\", "\", 0, $STR_CASESENSE) ; increases speed
  If @extended > $iDeep Then
    $iDeep = @extended
    $sFolder = $aList[$i]
  EndIf
Next
ConsoleWrite($sFolder & @CRLF)

 

Link to comment
Share on other sites

That's a really simple but also clever way to do it @Nine, well done, I like it!

Best regards
Sven

Stay innovative!

Spoiler

🌍 Au3Forums

🎲 AutoIt (en) Cheat Sheet

📊 AutoIt limits/defaults

💎 Code Katas: [...] (comming soon)

🎭 Collection of GitHub users with AutoIt projects

🐞 False-Positives

🔮 Me on GitHub

💬 Opinion about new forum sub category

📑 UDF wiki list

✂ VSCode-AutoItSnippets

📑 WebDriver FAQs

👨‍🏫 WebDriver Tutorial (coming soon)

Link to comment
Share on other sites

@Eazy-P  after @Nine's post I understood exactly what you wanted, because as usual it gives targeted solutions

 

@Nine I can't believe it took out only the deepest folder (among 4884) in only 0.649 seconds
I look at it, I look at it but I don't understand how it works, what is the meaning of replacing \ with \ (although I see ; increases speed , but I don't understand)
How does it work?

 

Edited
OK got it :)
Returns the new string with the number of replacements performed stored in the @extended macro.

Edited by ioa747

I know that I know nothing

Link to comment
Share on other sites

I wrote my own little recursive search after testing out @Nines solution on just my C:\ drive. It took around 150s to enumerate all the folders (gets faster running it multiple times, seems like), then around 1.5s to actually search the array (~340,000 folders). My solution obviously has less features available than _FileListToArrayRec, but speeds it up a lot by not having to build an array:

#include <File.au3>
#include <FileConstants.au3>
#include <StringConstants.au3>
__cLog('Starting...')
Global $gsSearchFolder = 'C:\'
Global $hTimer = TimerInit()
Global $iMax
Global $aList = _FileListToArrayRec($gsSearchFolder, "*", $FLTAR_FOLDERS, $FLTAR_RECUR)
If @error Then
    $iMax = 0
Else
    $iMax = $aList[0]
EndIf
__cLog('Total folders: ' & $iMax & ', loaded in: ' & Round(TimerDiff($hTimer), 2) & ' ms')
Global $iDeep = 0, $sFolder = ''
$hTimer = TimerInit()
For $iFolder = 1 To $iMax
    StringReplace($gsSearchFolder & $aList[$iFolder], "\", "\", 0, $STR_CASESENSE)  ; $STR_CASESENSE increases speed
    If @extended > $iDeep Then
        $iDeep = @extended
        $sFolder = $aList[$iFolder]
    EndIf
Next
__cLog('Depth: ' & $iDeep & ', processed in: ' & Round(TimerDiff($hTimer), 2) & ' ms')
__cLog($gsSearchFolder & $sFolder)

Global $iMaxDepth = 0, $iTotalFolders = 0, $iTotalFiles = 0
Global $sDeepestFolder = ''
Global $hTimer = TimerInit()
RecursiveSearch($gsSearchFolder)
__cLog('Depth: ' & $iMaxDepth & ', processed in: ' & Round(TimerDiff($hTimer), 2) & ' ms')
__cLog('Total folders searched: ' & $iTotalFolders & ', total files: ' & $iTotalFiles)
__cLog($sDeepestFolder)

Exit

Func RecursiveSearch($sFolder, $iMaxRecursion = -1, $iCurrentRecursion = 0)
    If $iMaxRecursion >= 0 And $iCurrentRecursion > $iMaxRecursion Then
        __cLog('Max recursion reached: ' & $iCurrentRecursion & '/' & $iMaxRecursion)
        Return SetError(1, 0, $iCurrentRecursion - 1)
    EndIf

    Local $sFile = ''
    $sFolder = $sFolder & '\'
    $sFolder = StringReplace($sFolder, '\\', '\', 0, $STR_CASESENSE)
    Local $sSearchFolder = $sFolder & '*'
    Local $hSearch = FileFindFirstFile($sSearchFolder)

    If $hSearch = -1 Then
        $hSearch = Null
;~      __cLog('No files: ' & $sSearchFolder)
        Return SetError(2, 0, $iCurrentRecursion - 1)
    EndIf

    While 1
        $sFile = FileFindNextFile($hSearch)
        If @error Then
;~          __cLog('Error: ' & @error)
            ExitLoop
        EndIf
        $iTotalFiles += 1
        If @extended = 1 Then
            $iTotalFolders += 1
            StringReplace($sFolder & $sFile & '\', '\', '\', 0, $STR_CASESENSE)
            If @extended > $iMaxDepth Then
                $iMaxDepth = @extended
                $sDeepestFolder = $sFolder & $sFile & '\'
                __cLog('New max depth: ' & $iMaxDepth & ', ' & $sDeepestFolder)
;~          ElseIf @extended = $iMaxDepth Then
;~              __cLog('Tied for (current) longest: ' & $sFolder & $sFile)
            EndIf
            $iCurrentRecursion = RecursiveSearch($sFolder & $sFile, $iMaxRecursion, $iCurrentRecursion + 1)
        EndIf
    WEnd

    FileClose($hSearch)
    $hSearch = Null

    Return SetError(0, 0, $iCurrentRecursion - 1)
EndFunc   ;==>RecursiveSearch

Func __cLog($sMsg)
    ConsoleWrite($sMsg & @CRLF)
EndFunc

And the output for me:

2023-03-05 10.25.47.087:    Starting...
2023-03-05 10.28.02.035:    Total folders: 342838, loaded in: 134947.48 ms
2023-03-05 10.28.03.469:    Depth: 21, processed in: 1434.45 ms
2023-03-05 10.28.03.470:    C:\Users\Raven\AppData\Local\Autodesk\webdeploy\production\b788673c90d05b91de61a3242d6fc03e30a0895b\Neutron\UI\Base\Gestura\Gestura\Wrappers\PPI\ppiapi-cpp\doc\cpp\html\search\

2023-03-05 10.28.40.066:    Depth: 21, processed in: 36596.04 ms
2023-03-05 10.28.40.066:    Total folders searched: 342838, total files: 1901158
2023-03-05 10.28.40.066:    C:\Users\Raven\AppData\Local\Autodesk\webdeploy\production\b788673c90d05b91de61a3242d6fc03e30a0895b\Neutron\UI\Base\Gestura\Gestura\Wrappers\PPI\ppiapi-cpp\doc\c\html\search\

135s vs 37s, similar resulting folder, just a bit different because of the scan/sort order, but otherwise same amount of folders processed. If you needed to find all folders that are at the same max depth you'd have to store them in an array or something and reset it each time you found a new max depth.

We ought not to misbehave, but we should look as though we could.

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