@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!
List Files Recursive mit Filter
- jacdelad
- Beiträge: 348
- Registriert: 03.02.2021 13:39
- Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
- Wohnort: Riesa
- Kontaktdaten:
Re: List Files Recursive mit Filter
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()
PureBasic 6.11/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/150TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/150TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Re: List Files Recursive mit Filter
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.
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.
- jacdelad
- Beiträge: 348
- Registriert: 03.02.2021 13:39
- Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
- Wohnort: Riesa
- Kontaktdaten:
Re: List Files Recursive mit Filter
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.
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.
PureBasic 6.11/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/150TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/150TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
-
- Beiträge: 120
- Registriert: 01.04.2011 21:59
Re: List Files Recursive mit Filter
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.
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.
- jacdelad
- Beiträge: 348
- Registriert: 03.02.2021 13:39
- Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
- Wohnort: Riesa
- Kontaktdaten:
Re: List Files Recursive mit Filter
...ist es eben nicht:
...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...
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()
PureBasic 6.11/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/150TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/150TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB