_FileListToRekursiv Update: 08.07.2011

  • Hi Leute!


    Jetzt genauso schneller wie mit Run(@ComSpec .... ! :DViel Schneller ;)
    Mit Wildcards Datei/Ordner suche !

    Update: 08.07.2011 Durch TheDude der gerne ein Parameter zum unterscheiden für Groß o. Kleinschreibung haben möchte, habe ich

    [autoit]

    $CaSen ;....

    [/autoit]

    hinzugefügt, ist nur in Kombination mit Flag 3 zu verwenden.

    Update: 11.05.2011 Individuell Suche eingebunden ( Suche marke eigenbau, Microsoft MS-DOS Wild Card Match, Benutzer eigen, RegExp Match ) u. suche nach leeren Ordner bei gleichbleibender Performance.
    Update: 11.02.2011 Funktion erweitert man kann festlegen ob das Array 0 basierend = anzahl(Index) oder nicht
    Update: 21.12.2010 zusatzparameter um die Tife des Teilbaum fest zu legen
    Update 19.12.2010 noch ein wenig schneller.
    Update: 19.11.2010 - Unnötige For u. Next schleife Entfernt, Ein zusatz $Mehr ist eingebaut worden um mehrere Laufwerke auf einmal zu speichern Also ein Speicher bei mehreren aufrufen.

    Func:

    Spoiler anzeigen
    [autoit]

    ;===================================================================================================================================#
    ;Function Name....: _FileListToRekursiv($Path, $Wildc = '*', $iFlag = 0, $iTB = 0, $iIntex = 0, $More = False, Const $CaSen = 0)
    ;Description......: Auflistung von Dateien u. o. Ordner (Rekursiv)
    ;$Path............: Pfad angabe
    ;$Wildc...........: '*' (Standart) Suchbegrif u. o. Wildcards nur (*) möglich
    ; bei Wildcards u. suchbegriff ist $iFlag auf '3' zu setzen
    ; es ist auch möglich mehrere suchbegriffe zu suchen z.B *.wma,*.mp3,*.txt getrennt mit ','
    ;
    ;$iFlag...........: '0' (Standart), Datein u. Ordner
    ; '1' nur Datein
    ; '2' nur Ordner
    ; '3' um mit suchbegriffen zu suchen *.txt
    ; '4' Microsoft MS-DOS Wild Card Match (nur ein Suchbegriff möglich)
    ; '5' Benutzer eigen, RegExp Match suche
    ; '6' suche für leere Ordner
    ;
    ;$iTB.............: '0' (Standart) für alle Unter-Verzeichnisse
    ;
    ;$iIndex..........: '0' (Standard), es fungiert jedes in den Trennzeichen enthaltene Zeichen als Trennmarkierung
    ; '1' es wird der gesamte Trennzeichenstring als Trennmarkierung genutzt
    ; '2' deaktiviert die Rückgabe der Anzahl im ersten Element. Dadurch wird das Array 0-basierend.
    ;
    ;$More............: 'False' (Standart) Ein duchlauf dann wird $RAS gelöscht
    ; 'True' Ein Speicher für wiederholten aufruf.
    ; !Wichtig! Bool ist zu verwenden
    ;
    ;$CaSen...........: ist nur mit Flag 3 zu Verwenden auf alle anderen Flags, hat Case-Sensitiv keine auswirkung.
    ; 0 = Groß- und Kleinschreibung werden nicht berücksichtigt (Standardwert).
    ; 1 = Berücksichtigt Groß- und Kleinschreibung.
    ; 2 = Groß- und Kleinschreibung werden nicht berücksichtigt. Es findet ein einfacherer schnellerer Vergleich statt
    ;
    ;Return Value(s)..: Array mit den gefundenen Dateien u. o Ordner
    ;
    ;error............: -1 unzulässiges zeichen
    ; -2 error Flag
    ; -3 es konnte kein Array erstellt werden
    ; -4 suche war erfolglos o. Dll aufruf ist gescheitert
    ;
    ;
    ;
    ;Author(s)........: Kleiner (http://www.autoit.de)
    ;====================================================================================================================================#

    [/autoit] [autoit][/autoit] [autoit]

    ;================================================================================ Variable - Constante#
    Global Static $__K32 = DllOpen('Kernel32'); DllCall( Reparse Point )
    Global Static $__Shl = DllOpen('Shlwapi'); DllCall( Microsoft MS-DOS Wild Card Match )
    Global $FN
    Global $RP
    Global $Ex
    Global $RAS
    Global $Spec
    Global $While
    Global $iCP_Len
    Global $casesense
    Global Const $IHV = 0xFFFFFFFF; INVALID_HANDLE_VALUE = -1
    Global Const $REPARSE_POINT = 0x400; FILE_ATTRIBUTE_REPARSE_POINT = 1024
    Global Const $sBack = '\', $sDelim = '|', $sW = '*'
    ;=====================================================================================================#

    [/autoit] [autoit][/autoit] [autoit]

    Func _FileListToRekursiv($Path, Const $Wildc = '*', Const $iFlag = 0, Const $iTB = 0, Const $iIntex = 0, Const $More = False, Const $CaSen = 0)
    $iCP_Len = ''
    If $iTB Then $iCP_Len = StringLen($Path) + 1
    If Not IsBool($More) Or Not $More Then $RAS = ''
    $Path = StringRegExpReplace($Path, '[\\/]+\z', $sBack) & $sBack
    If Not FileExists($Path) Then Return SetError(1, 0, '')
    If IIF($iFlag = 5, False, StringRegExp($Wildc, '[\\/:><\|]|(?s)\A\s*\z')) Then Return SetError(1, 0, -1)
    If ($iFlag < 0 Or $iFlag > 6) Then Return SetError(2, 0, -2)
    If Not $iFlag Or $iFlag = 2 Then $RAS &= $sDelim & $Path
    If $iFlag = 3 Then
    Local $aW_s = StringSplit($Wildc, ',')
    If Not IsArray($aW_s) Then Return SetError(3, 0, -3)
    Local $aW_s2[$aW_s[0]][3]
    $casesense = $CaSen
    For $i = 1 To $aW_s[0]
    $aW_s2[$i - 1][0] = (StringLeft($aW_s[$i], 1) = $sW) + IIF(StringRight($aW_s[$i], 1) = $sW, 2, 0)
    $aW_s2[$i - 1][1] = StringReplace($aW_s[$i], '*', '')
    $aW_s2[$i - 1][2] = StringLen($aW_s2[$i - 1][1])
    Next
    EndIf
    ToRekursiv(FileFindFirstFile($Path & $sW), $Path, IIF(IsDeclared('aW_s2'), Execute('$aW_s2'), $Wildc), $iFlag, $iTB)
    If Not $RAS Then Return SetError(4, 0, -4)
    Return StringSplit(StringTrimLeft($RAS, 1), $sDelim, $iIntex)
    EndFunc ;==>_FileListToRekursiv

    [/autoit] [autoit][/autoit] [autoit]

    Func ToRekursiv($HWnd, $Path, $Wildc, $iFlag, $iTB, $FL = '')
    If StringInStr($Path, $sBack, False, $iTB, $iCP_Len) Then Return True
    If $HWnd = $IHV And $iFlag = 6 Then $RAS &= $sDelim & StringTrimRight($Path, 1)
    $While = $HWnd <> $IHV
    While $While
    $FN = FileFindNextFile($HWnd)
    If @error Then ExitLoop
    $Ex = @extended
    Switch $iFlag
    Case 0
    $RAS &= $sDelim & $Path & $FN
    If $Ex Then $FL &= $sDelim & $Path & $FN & $sBack
    Case 1
    Switch $Ex
    Case 0
    $RAS &= $sDelim & $Path & $FN
    Case 1
    $FL &= $sDelim & $Path & $FN & $sBack
    EndSwitch
    Case 2
    If Not $Ex Then ContinueLoop
    $RAS &= $sDelim & $Path & $FN
    $FL &= $sDelim & $Path & $FN & $sBack
    Case 3
    If $Ex Then $FL &= $sDelim & $Path & $FN & $sBack
    If IsArray($Wildc) Then
    For $i = 0 To UBound($Wildc) - 1
    Switch $Wildc[$i][0]
    Case 1
    If Not StringCompare(StringRight($FN, $Wildc[$i][2]), $Wildc[$i][1], $casesense) Then $RAS &= $sDelim & $Path & $FN
    Case 2
    If Not StringCompare(StringLeft($FN, $Wildc[$i][2]), $Wildc[$i][1], $casesense) Then $RAS &= $sDelim & $Path & $FN
    Case 3
    If StringInStr($FN, $Wildc[$i][1], $casesense, 1) Then $RAS &= $sDelim & $Path & $FN
    EndSwitch
    Next
    EndIf
    Case 4
    If $Ex Then $FL &= $sDelim & $Path & $FN & $sBack
    $Spec = DllCall($__Shl, 'Bool', 'PathMatchSpecW', 'wstr', $FN, 'wstr', $Wildc)
    If @error Then Return True
    If $Spec[0] Then $RAS &= $sDelim & $Path & $FN
    Case 5
    If $Ex Then $FL &= $sDelim & $Path & $FN & $sBack
    If StringRegExp($FN, $Wildc) Then $RAS &= $sDelim & $Path & $FN
    Case 6
    If $Ex Then $FL &= $sDelim & $Path & $FN & $sBack
    EndSwitch
    WEnd
    FileClose($HWnd)
    If Not $FL Then Return True
    For $For In StringSplit(StringTrimLeft($FL, 1), $sDelim, 2)
    $RP = DllCall($__K32, 'Dword', 'GetFileAttributesW', 'wstr', $For)
    If @error Then Return True
    Switch BitAND($RP[0], $REPARSE_POINT)
    Case False
    ToRekursiv(FileFindFirstFile($For & $sW), $For, $Wildc, $iFlag, $iTB)
    Case Else
    ContinueLoop
    EndSwitch
    Next
    EndFunc ;==>ToRekursiv

    [/autoit] [autoit][/autoit] [autoit]

    ;===================================================================================================================================#
    ;Function Name....: IIF($expr, $Truepart = True, $Falsepart = False)
    ;
    ;Description......: If Abfrage
    ;$expr............: Wert zu Prüfung
    ;$Truepart........: Wenn Wert bei der Prüfung Wahr = ausgabe ( z.B True [Standart])
    ;$Falsepart.......: Wenn Wert bei der Prüfung Falsch = ausgabe ( z.B False [Standart])
    ;Return Value(s)..: Auswertung der Prüfung True/False/Benutzer(Ausgabe)
    ;
    ;Author(s)........: Kleiner (http://www.autoit.de)
    ;====================================================================================================================================#
    Func IIF($V_Expr, $F_True = True, $F_False = False)
    If $V_Expr Then Return $F_True
    Return $F_False
    EndFunc ;==>IIF

    [/autoit]


    LG Kleiner

  • Update

    Habe die func ein wenig schneller gemacht Dopelt so schnell bei mir C:\ vorher 5,67 sec. jetzt 2,75 sec. rund 6000-7000 Ordner : 0,700 sec. für rund 1000 Ordner

    Post#1


    LG Kleiner

  • Schon mal gegen die rekursive Dateiauflistung (per Objekt) von Bugfix antreten lassen?
    Die neue _Filelisttoarray ist ja auch ganz flott.

    Ist das nachträgliche hinzufügen des ganzen Pfads überhaupt nötig? Vielleicht muss man nur den Rückgabewert von _Filelisttoarray anpassen und kann das Skript so beschleunigen?
    Ist nur ne Idee aus dem Kopf heraus, hab hier leider kein Autoit drauf.

  • Hey,

    zumindest das hier stimmt nicht ;)

    ->

    [autoit]

    ; Parameter(s): $OD 0 (Standard)

    [/autoit]


    $OD muss noch manuell als 0 deklariert werden, da es in der Func noch nicht drin ist.

    Ansonsten scheint es das zu machen, was soll

    _FileList.au3: C:\ 64755 Dateien + Ordner in 9427,276 ms
    _GetFilesFolder_Rekursiv.au3: C:\ 64762 Dateien + Ordner in 41435,611 ms (2. Versuch in 26840,345)

    BugFix listet 7 Dateien mehr, aber vom Speed her geschlagen

    getestet, jeweils

    [autoit]

    $start = TimerInit()
    ;Function
    _ArrayDisplay($blubb, TimerDiff($start))

    [/autoit]

    PS: es heißt übrigens PHASE =)

  • Hi sc4ry!


    Soweit ich getestet habe listen beide immer das gleich ausser das die datein zB. auf C:\ nicht nacheinander afgelistet werden bei mir erst 3 dann kommen 100 Ordner
    dann die restlichen Datein oder noch mal weiter hinten, muß mal sehn wie sich das ändern läst!


    LG Kleiner

  • Hallo kleiner27,

    bekomme die _filelist.au3 (aktuell aus #1) nicht zum starten. Die bisherigen Änderungen brachten mich zwar immer einen Schritt weiter (immer 1. Fehler beseitigt), doch dann steigt das Skript an einer anderen Stelle aus. Kann es sein dass du Variablennamen zustark verkürzt hast,

    mfg (Auto)Bert

  • Guten Morgen!

    autoBert


    Also ich kann mir dein Fehler nur so erklären das wenn du
    zwei o. dreimal hintereinander die Func aufrufst dann ist er raus gesprungen
    den Bug habe ich behoben das lag an den Variablen und ReDim da manche den wert beibehalten haben und dazu kam es zu Fehlern! ;)

    Oder du benutz noch die alten Funktion aufrufe! :D


    Update: Post#1


    LG Kleiner

  • Hi sc4ry!

    Ich muste ein wenig erweitern!

    [autoit]

    ;==========================================================================================================
    ; Function Name: _FilesListRekursiv($P, $G = True, $O = 0)
    ;
    ; Description: Auflistung von Dateien und Ordnern
    ; $P Pfad
    ; $G 1 (Standart) wie viele Pfade / angabe zB 1 für C: oder 3 für C: D: E: nacheinader Durchsucht
    ; Parameter(s): $O 0 (Standard) Gibt Dateien und Ordner zurück, 1 Gibt nur Dateien zurück [ nur für 1 Pfad ]
    ; 2 Gibt nur Ordner zurück
    ;
    ; Return Value(s): Array (Standard) mit den gefundenen Pfaden der Dateien und/oder Ordner
    ;
    ; Author(s): (http://www.autoit.de) Kleiner27 <22.02.2010 23:00>
    ;============================================================================================================

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    _FilesListRekursiv('c:', 0, 2)

    [/autoit]


    LG Kleiner

  • Fehler lag an mir.

    Also speedtechnisch:

    1. Lauf 66694ms
    2. Lauf 9904
    3. Lauf 9324

    Also ich muss sagen, beim ersten Lauf ist das Teil wesentlich langsamer als bei der 1. Version ... danach ist der Wert gut

    Das Betriebssystem "cached" Dateien und deshalb ist der 1. Lauf eigentlich der tatsächlich relevante Wert! Nach jedem Durchlauf müsste man den Rechner durchstarten und neu messen, damit die Ergebnisse nicht verfälscht werden!
    Darum werden auch HD Benchmarks auf Hardwareebene programmiert, damit die Ergebnisse durch das Cachen nicht beinflusst werden!

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Guten Morgen!


    UEZ
    Richtig der erste wert ist die tatsechliche zeit, aber erstaunlich das autoit doch garnicht so langsam ist in manchen momenten ist die Func von mir im Kaltstart bis zu 4 sec. schneller als @ComSpec a.(CMD) nur bei datei suche ist sie um 100 ms langsamer.

    Bin im Tunig Fieber! :D

    Edit: Die idee kam als ich die rekursive Dateiauflistung (per Objekt) von Bugfix u. Oscar sien Treeview FileExplorer mir ausgibig anschute! ( Top die Beiden) :thumbup:

    LG Kleiner

    Einmal editiert, zuletzt von kleiner27 (25. Januar 2010 um 08:04)