Ich weiß was ihr denkt: "Schon wieder, so wie jede Woche, eine weitere Funktion zur Auflistung aller Dateien und Ordner im gesamten Verzeichnisbaum..."
Nun ... ja - aber nicht ganz.
Alle bisherigen Ansätze welche ich bisher dazu gesehen habe basierten auf einem rekursiven Ansatz (wenn es doch etwas anderes gibt - berichtigt mich).
Ich hab daher mal eine entsprechende Funktion geschrieben welche ohne Rekursion auskommt:
Spoiler anzeigen
#include <Array.au3>
[/autoit] [autoit][/autoit] [autoit]$Array = _FL2Arr(@WindowsDir, '*.exe', 1)
_ArrayDisplay($Array)
; #FUNCTION# ====================================================================================================================
; Name...........: _FL2Arr
; Description ...: Gibt ein Array mit Dateien bzw. Unterordnern im gesamten Verzeichnisbaum zurück
; Syntax.........: _FL2Arr($sStDir, [$sPat = '*', [$iFlag = 0]])
; Parameters ....: $sStDir - Startverzeichnis
; $sPat - Optional: Pattern zur Filterung (Stichwort: "WildCards")
; $iFlag - Optional: Flag ob nur Dateien, Ordner oder beides gesucht werden sollen
; |$iFlag=0(Default) Gibt beides zurück
; |$iFlag=1 Gibt nur Dateien zurück
; |$iFlag=2 Gibt nur Ordner zurück
; Return values .: @Error - 1 = Fehler beim erstellen der Queue
; |2 = Startverzeichnis existiert nicht.
; |3 = ungültiger Wert für $iFlag
; Author ........: AspirinJunkie
; Modified.......:
; Remarks .......: Benötigt .Net
; Related .......:
; Link ..........:
; Example .......: No
; Note ..........:
; ===============================================================================================================================
Func _FL2Arr($sStDir, $sPat = '*', $iFlag = 0)
Local $cSQueue = ObjCreate("System.Collections.Queue")
If @error Then Return SetError(1, 1, -1)
Local $cRetQu = ObjCreate("System.Collections.Queue")
If @error Then Return SetError(1, 2, -1)
Local $FFFF, $FFNF, $sDir
$sPat = StringReplace($sPat, "\", "\\")
$sPat = StringReplace($sPat, ".", "\.")
$sPat = StringReplace($sPat, "*", ".*")
$sPat = '^' & $sPat & '$'
If StringRight($sStDir, 1) = '\' Then $sStDir = StringTrimRight($sStDir, 1)
If Not FileExists($sStDir) Then Return SetError(2, 0, "")
If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(3, 0, "")
$cSQueue.Enqueue($sStDir)
[/autoit] [autoit][/autoit] [autoit]While $cSQueue.Count > 0
$sDir = $cSQueue.Dequeue
$FFFF = FileFindFirstFile($sDir & '\*')
If $FFFF <> -1 Then
Do
$FFNF = FileFindNextFile($FFFF)
If @error Then ExitLoop
If @extended Then
$cSQueue.Enqueue($sDir & '\' & $FFNF)
If $iFlag <> 1 And StringRegExp($FFNF, $sPat) Then $cRetQu.Enqueue($sDir & '\' & $FFNF)
Else
If $iFlag < 2 And StringRegExp($FFNF, $sPat) Then $cRetQu.Enqueue($sDir & '\' & $FFNF)
EndIf
Until 0
EndIf
WEnd
If $cRetQu.Count > 0 Then
Return $cRetQu.ToArray
Else
Local $Ret[1] = [0]
Return $Ret
EndIf
EndFunc ;==>_FL2Arr
Das ist vor allem schön für die Speichernutzung da der obligatorische Stackframe für jeden Rekursionsfunktionsaufruf entfällt.
Nun aber warum das ganze?:
Ich wollte es mal hochstellen um mal einen anderen Ansatz zu demonstrieren und eine Vorlage für Erweiterungen, Verbesserungen etc. zu bieten.
Beispielsweise könnte man alle Unterordner in einem Verzeichnis auflisten wenn man das Prinzip entsprechend nutzt:
Spoiler anzeigen
#include <Array.au3>
[/autoit] [autoit][/autoit] [autoit]$Array = Ordner(@SystemDir)
_ArrayDisplay($Array)
;Gibt ein Array aller Ordner im Verzeichnisbaum zurück
Func Ordner($sStDir)
Local $cStack = ObjCreate("System.Collections.Stack")
Local $cRetSt = ObjCreate("System.Collections.Stack")
Local $oFS = ObjCreate("Scripting.FileSystemObject")
$cStack.Push($oFS.GetFolder($sStDir))
[/autoit] [autoit][/autoit] [autoit]While $cStack.Count > 0
$oSF = $cStack.Pop
$cRetSt.Push($oSF.Path)
For $oF In $oSF.SubFolders
$cStack.Push($oF)
Next
WEnd
Return $cRetSt.ToArray
EndFunc ;==>Ordner
So ich hoffe der ein oder andere sieht darin eine brauchbare Alternative für seine Zwecke.