FindFile

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
mpz
Beiträge: 505
Registriert: 14.06.2005 15:53
Computerausstattung: Win 11 Pro, 48 GB Ram, Intel I7 CPU und RX4070 Grafikkarte, PB (4/5) 6.12LT
Wohnort: Berlin, Tempelhof

Beitrag von mpz »

Ja,

da fällt mir nur noch ein Dir zu Deiner guten Lösung zu gratulieren. An die Idee mit den Listen habe ich zwar gedacht, aber nicht umgesetzt.

Das Bessere ist immer ein Feind des Guten. Das mit dem Speicherleck ist wirklich Böse Böse. Soll nicht mehr vorkommen :)

Gruß Michael
Working on :lol: - LibSGD - MP3D Engine - 8)
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

NicTheQuick hat geschrieben:Versucht mal folgendes:
PC neustarten und Code ausführen. -> Dauert lange.
Code direkt danach nochmal ausführen. -> Geht sehr schnell.
Grund: Alle Verzeichnisinhalte wurden von Windows zwischengespeichert,
damit es beim nächsten Mal eben schneller geht.
Daher habe ich extra nochmal gesucht, nur eben mit HTM statt SYS. Reicht das nicht, um diese Zwischenspeicherung zu umgehen?

Und selbst wenn: Ist doch gut, dass der Code mit Hilfe der zwischenspeicherung so schnell geht. Kann ja sein, dass jemand, der das in seinem Programm einbaut auch mehrmals suchen muss.


@ mpz:
> da fällt mir nur noch ein Dir zu Deiner guten Lösung zu gratulieren.
Dankeschön :D

> Das mit dem Speicherleck ist wirklich Böse Böse. Soll nicht mehr vorkommen
ist ja nicht schlimm. Du kriegst von mir/uns ja keine Schimpfe. Hast ja nicht puttgemacht. Wollte nur eben drauf hinweisen. :allright:
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

AND51 hat geschrieben:Reicht das nicht, um diese Zwischenspeicherung zu umgehen?
nein, das reicht nicht. Es wird ja die Filestruktur gecached, nicht die
Suchergebnisse.

Um den Cache zu leeren, reicht es in der Regel, eines dieser
Speicheroptimierungsprogramm zu verwenden. Die sind für den normalen
Gebrauch ziemlich sinnfrei, können aber prima nicht mehr genutzte
Speicherbereiche für Performancetests freiräumen. ;-)
AND51 hat geschrieben:Und selbst wenn: Ist doch gut, dass der Code mit Hilfe der zwischenspeicherung so schnell geht. Kann ja sein, dass jemand, der das in seinem Programm einbaut auch mehrmals suchen muss.
ja, das ist aber nicht der Verdienst Deines Codes, sondern der Tatsache,
dass das OS zwischenspeichert ;-)

Die erzielten Such-Zeiten sind übrigens von mehreren Faktoren abhängig.
Neben der von NTQ erwähnten Zwischenspeicherung selbstredend u.a.
auch Festplattengröße und Zugriffszeiten.

Deswegen:
Thorium hat geschrieben:ungefähr gleich schnell wie die Windows-Suche.
Grüße ... Kiffi

Edit by NicTheQuick: Hab mal meine Abkürzung verbessert. :)
a²+b²=mc²
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

> ja, das ist aber nicht der Verdienst Deines Codes, sondern der Tatsache, dass das OS zwischenspeichert
Ja, das stimmt.

Als nächstes könnte man noch einen Callback einbauen, damit das Programm noch auf Messagesreagiert, dem Benutzer anzeigen kann, welcher Ordner gerade durchsucht wird oder eine Abbruch-Möglichkeit bieten kann.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

@NTQ: Sorry, wollte ich nicht! :oops: Was habe ich geschrieben? NTC, oder?
AND51 hat geschrieben:[...] dem Benutzer anzeigen kann, welcher Ordner gerade durchsucht wird oder
eine Abbruch-Möglichkeit bieten kann.
:allright:

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Kiffi hat geschrieben: :allright:
Alles klar, dann kommt hier:

Teil 3: FindMultipleFiles() mit Callback

Code: Alles auswählen

; AND51
; Nov-2007
; For free use, credits appreciated

EnableExplicit

Procedure myPersonalCallback(CurrentDir$)
	If MessageRequester("FindMultipleFiles()", CurrentDir$+#CRLF$+"Dies könnte dein Callback sein. Suche beenden?"+#CRLF$+"This could be your callback. Abort search?", #MB_ICONINFORMATION|#PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
		; Abort Search
		ProcedureReturn 0
	Else
		; Continue
		ProcedureReturn 1
	EndIf
EndProcedure

Procedure FindMultipleFiles(file.s, directory.s, ResultList.s(), recursive=1, *callback=0)
	PathAddBackslash_(@directory)
	If *callback
		If CallFunctionFast(*callback, directory) = 0
			ProcedureReturn -1
		EndIf
	EndIf
	Protected dir=ExamineDirectory(#PB_Any, directory, file)
	If dir
		While NextDirectoryEntry(dir) And recursive <> -1
			AddElement(ResultList())
				ResultList()=directory+DirectoryEntryName(dir)
		Wend
		FinishDirectory(dir)
	EndIf
	If recursive
		dir=ExamineDirectory(#PB_Any, directory, "")
		If dir
			While NextDirectoryEntry(dir)
				If DirectoryEntryType(dir) = #PB_DirectoryEntry_Directory And DirectoryEntryName(dir) <> "." And DirectoryEntryName(dir) <> ".."
					If FindMultipleFiles(file, directory+DirectoryEntryName(dir), ResultList(), 1, *callback) = -1
						Break
					EndIf
				EndIf
			Wend
			FinishDirectory(dir)
		EndIf
	EndIf
	ProcedureReturn CountList(ResultList())
EndProcedure

NewList suche.s()

Debug FindMultipleFIles("*.sys", "C:", suche(), 1, @myPersonalCallback())
ForEach suche()
	Debug suche()
Next

Alles wie gehabt: Brilliante Vorteile durch außergewöhnlch gut durchdachten Code. Um es kurz zu fassen: Es staubt immernoch! :lol:

Zusätzlich gibt es jetzt noch die Möglichkeit, einen Callback einzuklinken. Dies ist eine Prozedur, die von meiner Prozedur aufgerufen wird und den aktuell durchsuchten Ordner enthält. Wenn deine Prozedur 0 zurückgibt, bricht meine Prozedur die Suche ab, bei Werten ungleich 0 wird die Suche fortgesetzt.
Wird der Parameter "*callback" leer gelassen (also gleich null), dann macht die FUnktion nichts und arbeitet genauso wie Teil 2.

Hinweis an alle Callback-Profis: Dies ist das erste Mal, dass ich einen Code bereitstelle, der Callbacks anbietet. Habe ich soweit alles richtig gemacht? Oder muss ich was beachten?
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8812
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:
Der Callback ist schon richtig so.

Aber wo wir schonmal dabei sind:
Schreib doch grad noch einen Code, mit dem man nach mehreren Dateien
gleichzeitig suchen kann. Dabei soll die ODER-Verknüpfung gelten.
Ich empfehle dafür meine CompareWithWildcards-Procedure. :allright:
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

> Schreib doch grad noch einen Code, mit dem man nach mehreren Dateien gleichzeitig suchen kann. Dabei soll die ODER-Verknüpfung gelten
Oder Verknüpfung? Also, wenn ich nach *.sys und *.htm suche, zeigt er Dateien beiden Typs an? OK, mach ich eben, kein Problem.
Und es ist nichts gegen deinen Code, aber ich machs etwas eleganter bzgl. der Wildcards. :allright:


// Edit:
Hätte Fred endlich die Unterstützung für mehrere Pattern bei ExamineDirectory(), könntest du sofort loslegen, NtQ <)
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Voilà!

Weiter geht's: Teil 4 kann jetzt mehrere Dateien auf einmal suchen

Code: Alles auswählen

; AND51
; Nov-2007
; For free use, credits appreciated

EnableExplicit

Procedure myPersonalCallback(CurrentDir$)
	If MessageRequester("FindMultipleFiles()", CurrentDir$+#CRLF$+"Dies könnte dein Callback sein. Suche beenden?"+#CRLF$+"This could be your callback. Abort search?", #MB_ICONINFORMATION|#PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
		; Abort Search
		ProcedureReturn 0
	Else
		; Continue
		ProcedureReturn 1
	EndIf
EndProcedure

Procedure FindMultipleFiles(files.s, directory.s, ResultList.s(), recursive=1, *callback=0) ; use | to seperate files!
	PathAddBackslash_(@directory)
	If *callback
		If CallFunctionFast(*callback, directory) = 0
			ProcedureReturn -1
		EndIf
	EndIf
	Protected dir, i, n=CountString(files, "|")+1
	For i=1 To n
		dir=ExamineDirectory(#PB_Any, directory, StringField(files, i, "|"))
		If dir
			While NextDirectoryEntry(dir) And recursive <> -1
				AddElement(ResultList())
					ResultList()=directory+DirectoryEntryName(dir)
			Wend
			FinishDirectory(dir)
		EndIf
	Next
	If recursive
		dir=ExamineDirectory(#PB_Any, directory, "")
		If dir
			While NextDirectoryEntry(dir)
				If DirectoryEntryType(dir) = #PB_DirectoryEntry_Directory And DirectoryEntryName(dir) <> "." And DirectoryEntryName(dir) <> ".."
					If FindMultipleFiles(files, directory+DirectoryEntryName(dir), ResultList(), 1, *callback) = -1
						Break
					EndIf
				EndIf
			Wend
			FinishDirectory(dir)
		EndIf
	EndIf
	ProcedureReturn CountList(ResultList())
EndProcedure

NewList suche.s()

Debug FindMultipleFiles("*.pb*|purebasic_compilation*|purebasic.exe", "D:", suche(), 1, @myPersonalCallback())
ForEach suche()
   Debug suche()
Next
Handhabung wie gehabt. Bitte zum Suchen mehrerer Dateien diese mit einem Seknrechtstrich | trennen (wie bei OpenFileRequester())!
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Bisonte
Beiträge: 2470
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

Na das nenn ich mal nen Wettstreit ;)

Und wenn der Thread fertig ist (wird wohl nich passiern ;) ) haben wir nen neuen Dateimanager ...

Das wär doch was... :allright:
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Antworten