Verzeichnis rekursiv durchlaufen + Callback

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
#NULL
Beiträge: 2238
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

ich sehe da auch keine mögliche continue-verwendung.
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Hier die optimierte Porzedur mit meinen Änderungen. So müsste es eigentlich am schnellsten sein. Ich habe festgestellt, das man doch kein Continue braucht. Warum? Weil der CallBack doch aufgerufen wird, gleichgültig, ob es sich gerade um eine Datei oder einen Ordner handelt
Außerdem habe ich die Sache mit 'name.s' rausgeworfen, diese (Spaß-)Bremse war zudem noch nichteinmal protected :shock: OMG, wenn ich da nur an EnableExplicit denke...

Warum außerdem nicht dir protecten, wie es ja glücklicherweise geschah und gleichzeitig noch einen Wert zuweisen? So spart man sich auch noch eine zeile. Die überflüssigen Klammern bei IF-Abfragen habe ich auch entfernt.

Für Erbsenzähler: Um 3 Byte im Quellcode zu sparen habe ich den pattern$ *.* durch "" ersetzt, was laut Hilfe beides das gleiche ist.

Code: Alles auswählen

ProcedureDLL PBE_ScanPath(path.s, callbackProcedure.l) ; Scan the given path recursively and call callback (optimized by AND51)
    Protected dir=ExamineDirectory(#PB_Any, path, "") 
    If dir
        While NextDirectoryEntry(dir) 
            If DirectoryEntryName(dir) <> "." And DirectoryEntryName(dir) <> ".."
                    CallFunctionFast(callbackProcedure, dir, path)
                    If DirectoryEntryType(dir) = #PB_DirectoryEntry_Directory
                           PBE_ScanPath(path + DirectoryEntryName(dir) + "\", callbackProcedure)
                    EndIf
            EndIf
        Wend 
        FinishDirectory(dir) 
    EndIf 
EndProcedure
  • 14 Zeilen Code, im Gegensatz zu vorher: 19 Zeilen
    Nun ist der Code fehlerfrei


@ Didelphodon, hier noch ein kleiner trick für dich :wink: If und else kannst du zusammensetzen zu ElseIf, also warum schreibst du dann noch
>Else
> name.s = DirectoryEntryName(dirId)
> If (name <>
Würde einfacher gehen:
> ElseIf If (name <> ........
Ganz nebenbei sparst du dir auch die Zweite IF-Abfrage.

@ MVXA: ASM-Handbuch? Nee, das habe ich aus der PB Hilfe. Aber ich glaube, es wird langsam Zeit, ins ASM Geschäft einzusteigen... Muss nur noch gucken, ob's auch Tuts oder Helps für besonders hoffunglose Fälle wie mich gibt :roll:

> ausnahmsweise
Hab ich da was gehört oder hast du dich gerade nur geräuspert? :wink:
Zuletzt geändert von AND51 am 12.12.2006 15:33, insgesamt 2-mal geändert.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

@AND51:
Da warst du wohl ein wenig zu schnell und hast auch nichts getestet. :)

Du benutzt teilweise dir und teilweise dirId und dem Callback übergibst du
auch nur zwei Nullen. Du hast auch #PB_DirectoryEntry_Directory und
#PB_DirectoryEntry_File vertauscht. :roll:

Also wie war das nochmal mit dem EnableExplicit? :twisted:


Zudem frage ich mich sowieso, warum dem Callback dir Directory-ID
übergeben wird. Ich hab alles mal geändert und ein Beispiel dazu gepackt.
Die Funktion gibt die Anzahl der gefundenen Dateien zurück.

Code: Alles auswählen

EnableExplicit

Procedure PBE_ScanPath(Path.s, *callbackProc) ; Scan the given path recursively and call callback (format dirId.l, path.s) (optimized by AND51)
  Protected dir.l, name.s, files.l
  
  If *callbackProc = 0 : ProcedureReturn #False : EndIf
  
  If Right(Path, 1) <> "\" : Path + "\" : EndIf
  
  dir = ExamineDirectory(#PB_Any, Path, "")
  If dir
    While NextDirectoryEntry(dir)
      name = DirectoryEntryName(dir)
      If name <> "." And name <> ".."
        If DirectoryEntryType(dir) = #PB_DirectoryEntry_Directory
          files + PBE_ScanPath(Path + name + "\", *callbackProc)
        Else
          files + 1
          CallFunctionFast(*callbackProc, Path + name)
        EndIf
      EndIf
    Wend
    FinishDirectory(dir)
    ProcedureReturn files
  EndIf
  
  ProcedureReturn #False
EndProcedure

Procedure FileCallback(File.s)
  Debug File
EndProcedure

Debug PBE_ScanPath("c:\programme\", @FileCallback())
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Hast Recht, ich muss da was übersehen haben...?

Aber trotzdem ist Didelphodon's Idee, 'dir' statt des Dateinamens zu übergeben, besser!

Denn dann kann der Calback auf das dir von ExamineDirectory zugreifen und die befehele DirectoryEntry*() benutzen!!

Sonst müsste ich ja Dateigröße, etc. alles manuell übergeben und so... Nene, da ist "unsere idee" unschlagbar!!!
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Didelphodon
Beiträge: 360
Registriert: 18.12.2004 13:03
Wohnort: Wien
Kontaktdaten:

Beitrag von Didelphodon »

@AND51: Danke für die Anmerkung bzgl. ElseIf, das habe ich damals anscheinend in der hitze des Gefechts übersehen - natürlich ist mir diese Facette der strukturierten Programmierung bekannt. :wink:
AND51 hat geschrieben:Aber trotzdem ist Didelphodon's Idee, 'dir' statt des Dateinamens zu übergeben, besser!

Denn dann kann der Calback auf das dir von ExamineDirectory zugreifen und die befehele DirectoryEntry*() benutzen!!
Genau deshalb auch mein Ansatz mit der Übergabe der Dir-ID. <)

LG Didel.
Das Leben ist ein sch*** Spiel, aber die Grafik ist irre!
Fighting for peace is like fuc*ing for virginity!
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Kein Problem.

Ich muss gestehen, dass ich es beim ersten Mal genauso wie NtQ gemacht hätte, als ich deine Idee jedoch sah... respekt! :allright: Ich wär erst beim 2. nachdenken drauf gekommen.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Antworten