_FileListToRekursiv Update: 08.07.2011

  • Hallo Kleiner,

    vielen Dank für diese super Funktion.

    Ich habe (erfolglos) versucht, diese so anzupassen, daß ich als Rückgabe ein zweidimensionales Array bekomme mit folgenden Inhalt:

    $AR[0][0] = Anzahl der Dateien
    $AR[1][0] = Datei- oder Ordnername inkl. Pfad
    $AR[1][1] = Erstellungsdatum der Datei /des Ordners
    $AR[1][2] = Datum der letzten Modifikation
    $AR[1][3] = Datum des letzten Zugriffs
    [...]

    Ich wollte die Informationen direkt beim Suchlauf ins Array schreiben. Natürlich kann ich auch das Suchergebnis in ein neues Array umlesen und dabei die benötigten Informationen hinzufügen, denke aber, daß es schneller geht, wenn man es in einem Rutsch macht.

    Hättest Du hier einen Tipp für mich, wie man das bewerkstelligen könnte? Oder wäre der Ansatz außerhalb der Funktion Deiner Meinung nach der bessere Weg?

    Vielen Dank vorab,
    Grüße

    TheDude 8)

    Cuiusvis hominis est errare, nullius nisi insipientis in errore perseverare.
    [Cicero, Philippica 12,2]

  • Hi!


    Ich würde die werte sammlung ausserhalb der Funktion machen, du kannst sie auch umbaunen wenn du willst!
    Beispiel:

    Spoiler anzeigen
    [autoit]

    #include <_ArrayMultiDisplay.au3>
    Local $iTimer = TimerInit()
    Local $aDaten = _File_List_S_Rekursiv(@TempDir)
    Local $aD_aS[$aDaten[0] + 1][4], $sE, $sV, $sL
    $aD_aS[0][0] = $aDaten[0]
    ConsoleWrite(Round(TimerDiff($iTimer)) & @CRLF)
    For $i = 1 To $aDaten[0]
    $sE = FileGetTime($aDaten[$i], 1)
    $sV = FileGetTime($aDaten[$i], 0)
    $sL = FileGetTime($aDaten[$i], 2)
    $aD_aS[$i][0] = $aDaten[$i]
    $aD_aS[$i][1] = $sE[2] & '.' & $sE[1] & '.' & $sE[0] & ' ' & $sE[3] & ':' & $sE[4] & ':' & $sE[5]
    $aD_aS[$i][2] = $sV[2] & '.' & $sV[1] & '.' & $sV[0] & ' ' & $sV[3] & ':' & $sV[4] & ':' & $sV[5]
    $aD_aS[$i][3] = $sE[2] & '.' & $sL[1] & '.' & $sL[0] & ' ' & $sL[3] & ':' & $sL[4] & ':' & $sE[5]
    Next
    _ArrayMultiDisplay($aD_aS, Round(TimerDiff($iTimer)))

    [/autoit]

    Lg Kleiner

  • Moin Kleiner,

    ... danke Dir für den Tipp. So in der Art (aber nicht so elegant) hatte ich es auch gelöst. ich werde Deinen Vorschlag aufgreifen - sieht sehr gut aus. :D

    Viele Grüße
    TheDude 8)

    Cuiusvis hominis est errare, nullius nisi insipientis in errore perseverare.
    [Cicero, Philippica 12,2]

  • häää bei mir kommen mit diesem code

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    $Pfad = "d:\"

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

    $avarray = _FileListToRekursiv($Pfad)
    _ArrayDisplay($avarray)

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

    ;===================================================================================================================================#
    ;~ Function Name....: _FileListToRekursiv($Pfad, $Wildc = '*', $Flag = 0, $Mehr = 0)
    ;
    ;~ Description......: Auflistung von Dateien
    ;~ $Pfad............: Pfad
    ;~ $Wildc...........: '*' (Standart) Suchbegrif u. o. Wildcards bei Wildcards mit o. suchbegriff $_Flag_ auf '3' setzen es ist auch
    ; möglich mehrere suchbegriffe zu suchen z.B (*wma,*mp3,*txt) o. (wma,mp3,txt) getrennt mit ','
    ;~ $Flag............: '0' (Standart) Datein u. Ordner '1' nur Datein '2' nur Ordner '3' um mit suchbegriffen zu suchen wie (*.txt)
    ;~ $Mehr............: '0' (Standart) Ein duchlauf dann wird $RAS gelöscht : '1' Ein Speicher für wiederholten aufruf.
    ;~ Return Value(s)..: Array mit den gefundenen Dateien u. o Ordner Array[0] endhält die anzahl (Fund)
    ;
    ;~ Author(s)........: Kleiner (http://www.autoit.de) # 19.11.2010 14:00 #
    ;====================================================================================================================================#

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

    Local $F
    Local $FN
    Local $RAS
    Local $Verz
    Local $Expan
    Local $sDelim = '\', $sDelim1 = '|'

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

    Func _FileListToRekursiv($Pfad, Const $Wildc = '*', Const $Flag = 0, Const $Mehr = 0)
    If Not $Mehr Then $RAS = ''
    $Pfad = StringRegExpReplace($Pfad, '[\\/]+\z', $sDelim) & $sDelim
    If Not FileExists($Pfad) Then Return SetError(1, 0, '')
    If StringRegExp($Wildc, '[\\/:><\|]|(?s)\A\s*\z') Then Return SetError(1, 0, '')
    If Not ($Flag = 0 Or $Flag = 1 Or $Flag = 2 Or $Flag = 3) Then Return SetError(1, 0, '')
    ToRekursiv($Pfad, StringReplace(StringReplace($Wildc, '*', ''), ',', $sDelim1), $Flag)
    If Not $RAS Then Return SetError(4, 4, '')
    Return StringSplit(StringTrimLeft($RAS, 1), $sDelim1)
    EndFunc ;==>_FileListToRekursiv

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

    Func ToRekursiv($Pfad, $Wildc, $Flag)
    Local $FL
    $F = FileFindFirstFile($Pfad & '*')
    If ($F <> -1) Then
    Do
    $FN = FileFindNextFile($F)
    If @error Then ExitLoop
    $Expan = @extended
    Switch $Flag
    Case 0
    Switch $Expan
    Case 0
    $RAS &= $sDelim1 & $Pfad & $FN
    Case 1
    $FL &= $sDelim1 & $FN & $sDelim
    $RAS &= $sDelim1 & $Pfad & $FN
    EndSwitch
    Case 1
    Switch $Expan
    Case 0
    $RAS &= $sDelim1 & $Pfad & $FN
    Case 1
    $FL &= $sDelim1 & $FN & $sDelim
    EndSwitch
    Case 2
    If Not $Expan Then ContinueLoop
    $FL &= $sDelim1 & $FN & $sDelim
    $RAS &= $sDelim1 & $Pfad & $FN
    Case 3
    If $Expan Then $FL &= $sDelim1 & $FN & $sDelim
    If StringRegExp($FN, $Wildc) Then $RAS &= $sDelim1 & $Pfad & $FN
    EndSwitch
    Until False
    EndIf
    FileClose($F)
    If Not $FL Then Return True
    $Verz = StringSplit(StringTrimLeft($FL, 1), $sDelim1, 2)
    For $For In $Verz
    If Not IsReparsePoint($Pfad & $For) Then ToRekursiv($Pfad & $For, $Wildc, $Flag)
    Next
    EndFunc ;==>ToRekursiv

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

    Func IsReparsePoint($FLS);progandy
    Dim Static $K32 = DllOpen('kernel32.dll')
    Dim $DA = DllCall($K32, 'dword', 'GetFileAttributesW', 'wstr', $FLS)
    If @error Then Return SetError(0, @error, 0)
    Return BitAND($DA[0], 1024) = 1024
    EndFunc ;==>IsReparsePoint

    [/autoit]

    den Fehler:
    (30) : ==> Variable used without being declared.:
    $Pfad = StringRegExpReplace($Pfad, '[\\/]+\z', $sDelim) & $sDelim
    $Pfad = StringRegExpReplace($Pfad, '[\\/]+\z', ^ ERROR

    steh gerade aufm Schlauch.

    ---
    In "Independence Day" konnten die Windows-Erdcomputer problemlos mit denen der Außerirdischen kommunizieren. Was sagt uns das über unseren lieben Bill Gates? :D
    ---

  • Ob das mit der lokalen Deklaration außerhalb einer Funktion (imho auch kein guter Stil) zusammenhängt?


    edit \

    Hehe ja die Deklaration (besser global) muss auch vor dem Funktionsaufruf geschehen.

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>

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

    ;===================================================================================================================================#
    ;~ Function Name....: _FileListToRekursiv($Pfad, $Wildc = '*', $Flag = 0, $Mehr = 0)
    ;
    ;~ Description......: Auflistung von Dateien
    ;~ $Pfad............: Pfad
    ;~ $Wildc...........: '*' (Standart) Suchbegrif u. o. Wildcards bei Wildcards mit o. suchbegriff $_Flag_ auf '3' setzen es ist auch
    ; möglich mehrere suchbegriffe zu suchen z.B (*wma,*mp3,*txt) o. (wma,mp3,txt) getrennt mit ','
    ;~ $Flag............: '0' (Standart) Datein u. Ordner '1' nur Datein '2' nur Ordner '3' um mit suchbegriffen zu suchen wie (*.txt)
    ;~ $Mehr............: '0' (Standart) Ein duchlauf dann wird $RAS gelöscht : '1' Ein Speicher für wiederholten aufruf.
    ;~ Return Value(s)..: Array mit den gefundenen Dateien u. o Ordner Array[0] endhält die anzahl (Fund)
    ;
    ;~ Author(s)........: Kleiner (http://www.autoit.de) # 19.11.2010 14:00 #
    ;====================================================================================================================================#

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

    Local $F
    Local $FN
    Local $RAS
    Local $Verz
    Local $Expan
    global $sDelim = '\'
    global $sDelim1 = '|'

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

    $path = "d:\"

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

    $avarray = _FileListToRekursiv($path)
    _ArrayDisplay($avarray)

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

    Func _FileListToRekursiv($Pfad, Const $Wildc = '*', Const $Flag = 0, Const $Mehr = 0)
    If Not $Mehr Then $RAS = ''
    $Pfad = StringRegExpReplace($Pfad, '[\\/]+\z', $sDelim) & $sDelim
    If Not FileExists($Pfad) Then Return SetError(1, 0, '')
    If StringRegExp($Wildc, '[\\/:><\|]|(?s)\A\s*\z') Then Return SetError(1, 0, '')
    If Not ($Flag = 0 Or $Flag = 1 Or $Flag = 2 Or $Flag = 3) Then Return SetError(1, 0, '')
    ToRekursiv($Pfad, StringReplace(StringReplace($Wildc, '*', ''), ',', $sDelim1), $Flag)
    If Not $RAS Then Return SetError(4, 4, '')
    Return StringSplit(StringTrimLeft($RAS, 1), $sDelim1)
    EndFunc ;==>_FileListToRekursiv

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

    Func ToRekursiv($Pfad, $Wildc, $Flag)
    Local $FL
    $F = FileFindFirstFile($Pfad & '*')
    If ($F <> -1) Then
    Do
    $FN = FileFindNextFile($F)
    If @error Then ExitLoop
    $Expan = @extended
    Switch $Flag
    Case 0
    Switch $Expan
    Case 0
    $RAS &= $sDelim1 & $Pfad & $FN
    Case 1
    $FL &= $sDelim1 & $FN & $sDelim
    $RAS &= $sDelim1 & $Pfad & $FN
    EndSwitch
    Case 1
    Switch $Expan
    Case 0
    $RAS &= $sDelim1 & $Pfad & $FN
    Case 1
    $FL &= $sDelim1 & $FN & $sDelim
    EndSwitch
    Case 2
    If Not $Expan Then ContinueLoop
    $FL &= $sDelim1 & $FN & $sDelim
    $RAS &= $sDelim1 & $Pfad & $FN
    Case 3
    If $Expan Then $FL &= $sDelim1 & $FN & $sDelim
    If StringRegExp($FN, $Wildc) Then $RAS &= $sDelim1 & $Pfad & $FN
    EndSwitch
    Until False
    EndIf
    FileClose($F)
    If Not $FL Then Return True
    $Verz = StringSplit(StringTrimLeft($FL, 1), $sDelim1, 2)
    For $For In $Verz
    If Not IsReparsePoint($Pfad & $For) Then ToRekursiv($Pfad & $For, $Wildc, $Flag)
    Next
    EndFunc ;==>ToRekursiv

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

    Func IsReparsePoint($FLS);progandy
    Dim Static $K32 = DllOpen('kernel32.dll')
    Dim $DA = DllCall($K32, 'dword', 'GetFileAttributesW', 'wstr', $FLS)
    If @error Then Return SetError(0, @error, 0)
    Return BitAND($DA[0], 1024) = 1024
    EndFunc ;==>IsReparsePoint

    [/autoit]

    Einmal editiert, zuletzt von nuts (22. November 2010 um 18:24)

  • :pinch: ja klar... danke!

    ---
    In "Independence Day" konnten die Windows-Erdcomputer problemlos mit denen der Außerirdischen kommunizieren. Was sagt uns das über unseren lieben Bill Gates? :D
    ---

  • Hi!

    Ich Bekomme den Fehler nicht ausser Wenn ich!

    [autoit]

    #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

    [/autoit]


    nutze und der sagt mir alle besser auf Global Deklaration Okay Post#1 geändert!

    Danke ;)


    Lg Kleiner

  • Die CPU sollte nicht der Flaschenhals sein sondern das Dateisystem.
    Wenn das Dateisystem so lange braucht um die Daten zu liefern kann die CPU auch nichts machen in der Zeit.
    Von daher ist es eher schön das die Auslastung so niedrig bleibt.

    Wenn du allerdings 20 CPU-Kerne hast dann ist das Skript mit seinen 5% Auslastung doch voll am Anschlag.... ;)

  • Hallo Kleiner,

    wenn ich nachfolgenden Aufruf verwende, dann "ignoriert" die Funktion die Suche nach einer bestimmten Datei und liefert mir im Array sämtliche Dateinamen auf der Partition D: zurück:

    $FileListe = _FileListToRekursiv("D:\","xyz123.dat",1,0,0,$Unwahr) ; $Unwahr = FALSE

    ... oder

    $FileListe = _FileListToRekursiv("D:\","xyz123.dat",1)

    Beide Aufrufe bringen mir das gleiche Ergebnis. Ich habe bereits Deine neueste Version der UDF verwendet. Was mache ich hier falsch? ?(

    Danke vorab für Deinen Tipp,
    Grüße

    TheDude

    Cuiusvis hominis est errare, nullius nisi insipientis in errore perseverare.
    [Cicero, Philippica 12,2]