Seite 2 von 2

Re: List Files Recursive mit Filter

Verfasst: 23.11.2022 09:33
von SMaag
@jacdelad
Danke, ich hab's mir nochmals angesehen. Ich hätte das jetzt für komplizierter gehalten ohne Rekursion. Geht tatsächlich mit 2 While Schleifen.
Ich kenn das seit je her als Rekursion und wäre gar nicht auf die Idee gekommen das anders zu machen. Man lernt einfach nie aus!

Re: List Files Recursive mit Filter

Verfasst: 23.11.2022 10:02
von jacdelad
Hier ein wenig optimiert und mit Maske. Da ich zu blöd bin die Dateimaske in RegEx zu übersetzen muss jedes Verzeichnis doppelt gescannt werden (einmal für die Unterordner und einmal für die Dateien mit Maske). Vielleicht weiß jemand, wie man die Dateimaske (z.B. "*.dll") in RegEx übersetzen kann, dann würde ein Durchlauf reichen.

Code: Alles auswählen

EnableExplicit

Procedure ListRecursive(Dir$,List Liste.s(),Maske$="*.*")
  Protected NewList DirList.s(),exa
  AddElement(DirList())
  DirList()=RTrim(Dir$,"\")
  Repeat
    FirstElement(DirList())
    Dir$=DirList()
    DeleteElement(DirList())
    exa=ExamineDirectory(#PB_Any,Dir$,"*.*")
    If exa
      While NextDirectoryEntry(exa)
        If DirectoryEntryType(exa)=#PB_DirectoryEntry_Directory
          If ReplaceString(DirectoryEntryName(exa),".","")<>""
            AddElement(DirList())
            DirList()=Dir$+"\"+DirectoryEntryName(exa)
          EndIf
        EndIf
      Wend
      FinishDirectory(exa)
    EndIf
    exa=ExamineDirectory(#PB_Any,Dir$,Maske$)
    If exa
      While NextDirectoryEntry(exa)
        If DirectoryEntryType(exa)=#PB_DirectoryEntry_File
          AddElement(Liste())
          Liste()=Dir$+"\"+DirectoryEntryName(exa)
          ;Attribute etc...
        EndIf
      Wend
    EndIf
  Until ListSize(DirList())=0
EndProcedure

Global NewList MyList.s()
OpenConsole()
ListRecursive("C:\Windows\System32",MyList(),"*.dll")
ForEach MyList()
  PrintN(MyList())
Next
PrintN("Fertig!")
Input()

Re: List Files Recursive mit Filter

Verfasst: 24.11.2022 08:50
von SMaag
hab jetzt mal aus Neugier die beiden Versionen für Files auflisten
1x recursiv und 1x ohne Rekursion (mit 2 While Schleifen) in der Grundausführung (also ohne Filter usw.)
gegeneinader getestet.
Auf meinem Rechner dauert eine komplette Auflistung eines relativ großen Verzeichnisbaums damit knapp 2sec (ab dem 2ten Anlauf, wenn alles im Cache ist). Die rekursive Version ist etwas langsamer (rund 7%). Meine aufwendige Version mit den ganzen Filtermöglichkeiten ist deutlich abgeschlagen.

Re: List Files Recursive mit Filter

Verfasst: 24.11.2022 09:28
von jacdelad
Ja, die Filter brauchen natürlich ihre Zeit (und Dinge wie Attribute ermitteln und so auch). Geschwindigkeitstests immer mit ausgeschaltetem Debugger machen, das Ergebnis kann erheblich anders aussehen!
Letztendlich kann der eine Algorithmus den anderen überholen, wenn man Netzwerkordner scannt oder besonders viele Dateien oder Ordner drin sind oder der Datenträger besonders schnell/langsam ist oder...
Ich bevorzuge weiterhin den nichtrekursiven Algorithmus, aber im Endeffekt ist das Ergebnis das, was zählt. Wenn ich alle Dateien suche kann ich das schnell in einem Durchlauf machen, wenn ich Dateifilter benötige, dann muss ich zwei machen (solange ich das nicht mir RegEx hinkriege). Hat halt alles Vor- und Nachteile und sollte immer an den Zweck angepasst sein.

Re: List Files Recursive mit Filter

Verfasst: 28.11.2022 22:46
von fabulouspaul
Das mit dem Wildcard-Ersatz als RegEx sollte nicht so schwierig sein.
Im Dateisystem steht '?' für genau ein beliebiges Zeichen, das ist bei einer RegEx ein '.'
Im Dateisystem steht '*' für beliebig viele beliebige Zeichen, das ist bei einer RegEx '.*'
Bleibt nur noch der echte Punkt im Dateisystem, den man in der RegEx mit '\.' abbilden müsste

Aus '*.dll' als Maske im Dateisystem wird also die RegEx '.*\.dll'

Achtung ist ungetestet, sollte aber funktionieren.

Re: List Files Recursive mit Filter

Verfasst: 29.11.2022 00:44
von jacdelad
...ist es eben nicht:

Code: Alles auswählen

EnableExplicit

Procedure ListRecursive(Dir$,List Liste.s(),Maske$="*.*")
  Protected NewList DirList.s(),exa,RegEx
  AddElement(DirList())
  DirList()=RTrim(Dir$,"\")
  Maske$=ReplaceString(Maske$,".","\.")
  Maske$=ReplaceString(Maske$,"$","\$")
  Maske$=ReplaceString(Maske$,"+","\+")
  Maske$=ReplaceString(Maske$,"(","\(")
  Maske$=ReplaceString(Maske$,")","\)")
  Maske$=ReplaceString(Maske$,"[","\[")
  Maske$=ReplaceString(Maske$,"]","\]")
  Maske$=ReplaceString(Maske$,"?",".")
  Maske$="^"+ReplaceString(Maske$,"*",".*")+"$"
  RegEx=CreateRegularExpression(#PB_Any,Maske$,#PB_RegularExpression_NoCase)
  Repeat
    FirstElement(DirList())
    Dir$=DirList()
    DeleteElement(DirList())
    exa=ExamineDirectory(#PB_Any,Dir$,"*.*")
    If exa
      While NextDirectoryEntry(exa)
        If DirectoryEntryType(exa)=#PB_DirectoryEntry_Directory
          If ReplaceString(DirectoryEntryName(exa),".","")<>""
            AddElement(DirList())
            DirList()=Dir$+"\"+DirectoryEntryName(exa)
          EndIf
        Else
          If MatchRegularExpression(RegEx,DirectoryEntryName(exa))
             AddElement(Liste())
             Liste()=Dir$+"\"+DirectoryEntryName(exa)
             ;Attribute etc...
          EndIf
        EndIf
      Wend
      FinishDirectory(exa)
    EndIf
  Until ListSize(DirList())=0
EndProcedure

Global NewList MyList.s()
OpenConsole()
ListRecursive("C:\Windows\System32",MyList(),"push*")
ForEach MyList()
  PrintN(MyList())
Next
PrintN("Fertig!")
Input()
...findet auch "pushobj.dll.mui". Wie gesagt, es gibt so viel zu beachten, dass ich das nicht weiter durchprobieren will. Allein schon die ganzen Ersatzzeichen einbauen...