Ordnerstruktur in datei schreiben

  • hey hab mal ne frage...im cmd wenn man da tree eingibt, bekommt man ja so einen Ordnerbaum
    geht sowas mit autoit, also dass dies bis zu 5 unterordnern in eine datei geschrieben wird

  • also ich habe mich mal rangemacht und das is dabei herausgekommen:

    Spoiler anzeigen
    [autoit]

    #include <File.au3>
    #include <Array.au3>
    Global $path = "D:\"
    $file = @ScriptDir&"\tree.txt"
    $result = ""
    $array1 = _FileListToArray($path, "*", 2)
    for $1 = 1 to $array1[0]
    $array2 = _FileListToArray($path&$array1[$1], "*", 2)
    for $2 = 1 to $array2[0]
    $array3= _FileListToArray($path&$array1[$1]&"\"&$array2[$2], "*", 2)
    for $3 = 1 to $array3[0]
    $array4= _FileListToArray($path&$array1[$1]&"\"&$array2[$2]&"\"&$array3[$3], "*", 2)
    for $4 = 1 to $array4[0]
    $array5= _FileListToArray($path&$array1[$1]&"\"&$array2[$2]&"\"&$array3[$3]&"\"&$array4[$4], "*", 2)
    for $5 = 1 to $array5[0]
    $result &= $path&$array1[$1]&"\"&$array2[$2]&"\"&$array3[$3]&"\"&$array4[$4]&"\"&$array5[$5] & @crlf
    FileWrite($file, $result)
    Next
    Next
    Next
    Next
    Next

    [/autoit]

    das funktioniert an sich ganz gut nur dass irgendwann ein error kommt und das skript sich beendet

  • mach hald in den for schleifen

    If @error Then exitloop

    es hängt davon ab, dass keine datei mehr verfügbar ist

  • also ich habe jetz unter jedem for if @error then exitloop geschrieben:

    Spoiler anzeigen
    [autoit]

    #include <File.au3>
    #include <Array.au3>
    Global $path = "D:\"
    $file = @ScriptDir&"\tree.txt"
    $result = ""
    $array1 = _FileListToArray($path, "*", 2)
    for $1 = 1 to $array1[0]
    if @error Then ExitLoop
    $array2 = _FileListToArray($path&$array1[$1], "*", 2)
    for $2 = 1 to $array2[0]
    if @error Then ExitLoop
    $array3= _FileListToArray($path&$array1[$1]&"\"&$array2[$2], "*", 2)
    for $3 = 1 to $array3[0]
    if @error Then ExitLoop
    $array4= _FileListToArray($path&$array1[$1]&"\"&$array2[$2]&"\"&$array3[$3], "*", 2)
    for $4 = 1 to $array4[0]
    if @error Then ExitLoop
    $array5= _FileListToArray($path&$array1[$1]&"\"&$array2[$2]&"\"&$array3[$3]&"\"&$array4[$4], "*", 2)
    for $5 = 1 to $array5[0]
    if @error Then ExitLoop
    FileWrite($file, $path&$array1[$1]&"\"&$array2[$2]&"\"&$array3[$3]&"\"&$array4[$4]&"\"&$array5[$5] & @crlf)
    Next
    Next
    Next
    Next
    Next

    [/autoit]

    probleme...es kommt immernoch mein error

    außerdem schaut euch das mal also da werden die pfade auch doppelt geschrieben

    Spoiler anzeigen
  • Wenn ich dieses Script ausführe komm da:
    C:\Dokumente und Einstellungen\Pride\Desktop\test.au3 (7) : ==> Subscript used with non-Array variable.:
    for $1 = 1 to $array1[0]
    for $1 = 1 to $array1^ ERROR

    Meine Projekte:
    ClipBoard Manager (beendet)
    Gutes ClipBoard Verwaltungs Programm mit nützlichen Funktionen.

    HTML Creator (beendet)
    Nützliches Tool um schnell ein eigenes HTML Dokument zu erstellen.

  • Spoiler anzeigen
    [autoit]

    #include <File.au3>
    #include <Array.au3>

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

    Global $path = "C:\"
    Global $1,$2,$3,$4,$5
    Dim $array1[1]
    Dim $array2[1]
    Dim $array3[1]
    Dim $array4[1]
    Dim $array5[1]
    $file = @ScriptDir&"\tree.txt"
    $result = ""
    $array1 = _FileListToArray($path, "*", 2)
    If IsArray($array1) Then
    for $1 = 1 to $array1[0]
    if @error Then ExitLoop
    $array2 = _FileListToArray($path&$array1[$1], "*", 2)
    If IsArray($array2) Then
    for $2 = 1 to $array2[0]
    if @error Then ExitLoop
    $array3 = _FileListToArray($path&$array1[$1]&"\"&$array2[$2], "*", 2)
    If IsArray($array3) Then
    for $3 = 1 to $array3[0]
    if @error Then ExitLoop
    $array4= _FileListToArray($path&$array1[$1]&"\"&$array2[$2]&"\"&$array3[$3], "*", 2)
    If IsArray($array4) Then
    for $4 = 1 to $array4[0]
    if @error Then ExitLoop
    $array5 = _FileListToArray($path&$array1[$1]&"\"&$array2[$2]&"\"&$array3[$3]&"\"&$array4[$4], "*", 2)
    If IsArray($array5) Then
    for $5 = 1 to $array5[0]
    if @error Then ExitLoop
    FileWrite($file, $path&$array1[$1]&"\"&$array2[$2]&"\"&$array3[$3]&"\"&$array4[$4]&"\"&$array5[$5] & @crlf)
    Next
    Else
    FileWrite($file, $path&$array1[$1]&"\"&$array2[$2]&"\"&$array3[$3]&"\"&$array4[$4]&"\"& @crlf)
    EndIf
    Next
    Else
    FileWrite($file, $path&$array1[$1]&"\"&$array2[$2]&"\"&$array3[$3]&"\"& @crlf)
    EndIf
    Next
    Else
    FileWrite($file, $path&$array1[$1]&"\"&$array2[$2]&"\"& @crlf)
    EndIf
    Next
    Else
    FileWrite($file, $path&$array1[$1]&"\"& @crlf)
    EndIf
    Next
    Else
    FileWrite($file, $path& @crlf)
    EndIf
    MsgBox(0,"Fertig","Fertig!")

    [/autoit]

    So scheint es bei mir zu klappen. Bin mir aber nicht sicher habs die tree.txt nur überflogen.

  • SEuBo
    zählervariablen sind lokale zählervariablen, solche niemals gobal anlegen. das könnte ins auge gehn. generell sollte man nie variablen global anlegen
    gut bei mir ist das jetzt auch der fall, aber nur weil ich keine richtige main habe sonst wären all diese auch local

    kopierter quellcode ist nie guter quellcode und dazu unübersichtlich

    dafür eignen sich doch so schön rekursive funktionen
    ich hab hier schnell mal eine geschrieben der dem treeview nahe kommen soll
    sie kann dabei sehr variabel gehalten werden in anzahl der zu listenden unterverzeichnisse

    Spoiler anzeigen
    [autoit]

    #Include <File.au3>

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

    $wurzelpfad = "C:"
    $datei_handle = FileOpen(@ScriptDir&"\tree.txt", 1)
    FileWrite($datei_handle, $wurzelpfad&"\"&@CRLF)
    _liste_baum($wurzelpfad, 5)
    FileClose($datei_handle)

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

    #cs _liste_baum($aktueller_pfad, $max[, $tab[, $counter)
    $aktueller_pfad --> Verzeichnis ohne \ am Ende
    $max --> wie viele unterpfade
    $tab --> funktionsintern --> beim 1. aufruf "" rest
    $counter --> funktionsintern --> (optional)
    #ce
    Func _liste_baum($aktueller_pfad, $max = -1, $tab = "", $counter = 0)
    If $counter < $max Or $max == -1 Then
    $aktuelle_liste = _FileListToArray($aktueller_pfad, "*")
    If IsArray($aktuelle_liste) Then
    For $i = 1 To $aktuelle_liste[0]
    $aktuelle_datei = $aktueller_pfad&"\"&$aktuelle_liste[$i]
    If StringInStr(Filegetattrib($aktuelle_datei), "D") Then
    _schreibe($tab&"|"&@TAB&$aktuelle_liste[$i])
    _liste_baum($aktuelle_datei, $max, $tab&@TAB, $counter+1)
    Else
    _schreibe($tab&@TAB&$aktuelle_liste[$i])
    EndIf
    Next
    EndIf
    EndIf
    EndFunc

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

    Func _schreibe($text)
    FileWrite($datei_handle, $text&@CRLF)
    EndFunc

    [/autoit]

    je nachdem, wenn die einrückung unerwünscht is einfach die tabs raushauen
    und wenn absolute pfade erwünscht sind, in dem funktionaufruf

    [autoit]

    _schreibe()

    [/autoit]

    die variable

    [autoit]

    $aktuelle_liste[$i]

    [/autoit]

    mit

    [autoit]

    $aktuelle_datei

    [/autoit]

    ersetzen

    3 Mal editiert, zuletzt von achim89 (25. Oktober 2009 um 02:24)

  • Zu aller erst: Danke. Ich bin immer für kontruktive Kritik und vor allem Hilfestellungen dankbar. Ich bin halt eigentlich noch ein ziemlicher Anfänger bezüglich der Programmierlogik. Das mit den global definitionen sollte ich mir ggf. wirklich mal abgewöhnen. Da ich aber nie 2 Varbiablen des selben namens ausgenommen $i, welches ich aber nie global definiere (so wie mans auch eigenltich tun sollte), in meinen eigenen Skripts verwende, is da bis jetzt noch nix schiefgegangen... Naja ich werd mir deine Lösung nochmal genauer anschauen - denn lernen kann auch daraus bestimmt wieder ne Menge...

    Gruß SEuBo

  • Also variablen sind global schlecht wiel sie über die ganze programmlaufzeit leben und dadurch können sich fehler einschleichen, außerdem liegen sie die ganze zeit im arbeitsspeicher was bei richtig dicken variablen schon spürbar sien kann

    hier mal ein beispiel
    die lokale variable ist auserhalb der do until schleife nicht bekannt
    wenn ich sie verändern möchte dann tu ich das mit call by reference

    das heißt, in der funktion habe ich ein anderen namen für die in der schleife lokale variable, verändere sie aber trotzdem direkt

    beispiel

    Spoiler anzeigen
    [autoit]

    Global $global = 200

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

    Do
    Local $lokal = 100

    Switch GUIGetMsg() ;irgendeine switch schleife
    case $global
    EndSwitch

    _wert($global, $lokal)

    MsgBox(0,"","Global: "&$global&" Lokal:"&$lokal)
    Until True

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

    Func _wert($wert1, ByRef $wert2)
    $wert1 = 1 ; das ist die globale variable, die nicht verändert wird
    $wert2 = 1; das ist die lokale variable, sie wird im wert verändert (siehe msgbox)
    EndFunc

    [/autoit]

    hast du programmieren mit autoit gelernt?
    falls du vorhast hinter die ganze logik, dateitypen etc zu kommen lern eine hochsprache wie c oder c++
    das ist nicht all zu schwer und schafft feste grundlagen

    • Offizieller Beitrag

    Achim89, theoretisch hättest Du recht, aber praktisch ist das bei AutoIt anders. Eine Variable, die Du nicht innerhalb einer Funktion deklarierst, ist bei AutoIt immer global, ganz gleich ob Du Dim, Local oder Global benutzt.
    Beispiel:

    Spoiler anzeigen
    [autoit]


    Global $global = 200

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

    Local $lokal = 100

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

    _wert()

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

    MsgBox(0, "", "Global: " & $global & " Lokal:" & $lokal)

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

    Func _wert()
    $lokal = 500
    EndFunc ;==>_wert

    [/autoit]

    Erst wenn Du das Hauptprogramm in eine Funktion (Main) packst, bleibt die lokale Variable nur innerhalb der Funktion gültig:

    Spoiler anzeigen
    [autoit]


    Global $global = 200
    Main()

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

    Func Main()
    Local $lokal = 100
    _wert()
    MsgBox(0, "", "Global: " & $global & " Lokal:" & $lokal)
    EndFunc

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

    Func _wert()
    $lokal = 500
    EndFunc ;==>_wert

    [/autoit]
  • Den Unterschied zwischen Global und Local definierter Variable kenn ich auch.
    Wie AutoIt Variablen verwaltet wusste ich auch noch ( hab da vor 1 oder 2 tagen noch nen Thread drüber gelesen )
    Locale variablen benutze ich allerdings nur in For-Schleifen. Alle anderen meiner in den Funktionen genutzen Vars sind global deklariert, weil ich viele davon in meinem Scripten Funktionsübergreifend nutzen muss. Sobald ich eine Variable in mehreren funktionen zu unterschieldichen Zwecken benutze, wird sie eh innerhalb jeder Funktion neu deklariert ( und zwar nicht local sondern global ).
    Das mit der Speichernutzung wusste ich nicht - das wird mir aber wahrscheinlich helfen die Sache von einem anderen Blickwinkel zu sehen.

    Zu deiner Frage: Ja "Programmieren" hab ich mit AutoIT gelernt. Wobei ich es aber eher als rumspielen bezeichnen würde :rofl:
    Eine Hochsprache werd ich mir in absehbarer Zeit auch aneignen. Aber ich denke dass es nicht C/C++ sondern eher Java sein wird. Bin in Sachen Programmieren ein recht ungeduldiger Mensch, weswegen ich zb in AutoIt alle 5-10 mins auf den F5 knopf haue. Nach allem was ich so gehört hab kann ich mir das in C eher nicht erlauben, da es dir keine Fehler anzeigt (lieg ich da jezt falsch?)
    Java hingegen soll genausoviel meckern wie zb AutoIT

    Code
    WARNING: $DoofeVariable: possibly used before declaration.


    Sowas is mir nur lieb und recht ! :thumbup:

    • Offizieller Beitrag

    Um mal auf die ursprüngliche Frage zurückzukommen: Das einlesen eines Verzeichnisses inkl. Unterverzeichnisse.
    Das geht am besten mit einer rekursiven Funktion:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    $sPath = @ScriptDir
    $aDirs = _RecursiveFileListToArray($sPath, '', 2)
    _ArrayDisplay($aDirs)
    $hFile = FileOpen(@ScriptDir & '\DirList.txt', 2)
    If $hFile <> -1 Then
    For $i = 1 To $aDirs[0]
    FileWriteLine($hFile, $aDirs[$i])
    Next
    FileClose($hFile)
    EndIf

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

    ;===============================================================================
    ; Function Name: _RecursiveFileListToArray($sPath[, $sPattern][, $iFlag][, $iFormat][, $iRecursion][, $sDelim])
    ; Description:: gibt Verzeichnisse (rekursiv) und/oder Dateien zurück, die einem RegExp-Pattern entsprechen
    ; Parameter(s): $sPath = Startverzeichnis
    ; $sPattern = ein beliebiges RexExp-Pattern für die Auswahl
    ; $iFlag = Auswahl
    ; 0 = Dateien & Verzeichnisse
    ; 1 = nur Dateien
    ; 2 = nur Verzeichnisse
    ; $iFormat = Rückgabeformat
    ; 0 = String
    ; 1 = Array mit [0] = Anzahl
    ; 2 = Nullbasiertes Array
    ; $iRecursion = Verzeichnisse rekursiv durchsuchen
    ; 0 = Nein
    ; 1 = Ja
    ; $sDelim = Trennzeichen für die String-Rückgabe
    ; Requirement(s): AutoIt 3.3.0.0
    ; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen
    ; Author(s): Oscar (http://www.autoit.de)
    ; Anregungen von: bernd670 (http://www.autoit.de)
    ;===============================================================================
    Func _RecursiveFileListToArray($sPath, $sPattern = '', $iFlag = 0, $iFormat = 1, $iRecursion = 1, $sDelim = @CRLF)
    Local $hSearch, $sFile, $sReturn = ''
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $hSearch = FileFindFirstFile($sPath & '*.*')
    If @error Or $hSearch = -1 Then Return SetError(1, 0, $sReturn)
    While True
    $sFile = FileFindNextFile($hSearch)
    If @error Then ExitLoop
    If StringInStr(FileGetAttrib($sPath & $sFile), 'D') Then
    If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
    If $iRecursion Then $sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0)
    ContinueLoop
    EndIf
    If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
    WEnd
    FileClose($hSearch)
    If $iFormat And $sReturn = '' Then Return StringSplit($sReturn, '', $iFormat)
    If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
    Return $sReturn
    EndFunc

    [/autoit]