CreateDirectoryPath()

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Ich habe hier eine Prozedur, die so arbeitet. Allerdings bin ich mir nicht sicher, ob die Prozedur funktioniert. Sie erstellt immer korrekt die Verzeichnisse, aber ich schaffe es nicht, die Prozedur bewusst zum scheitern zu bringen, um zu sehen, ob sie dann immernoch korrekt arbeitet:

Code: Alles auswählen

EnableExplicit
Procedure CreatePath(path.s)
	CompilerSelect #PB_Compiler_OS
		CompilerCase #PB_OS_Windows
			#Directory_Separator$="\"
		CompilerDefault
			#Directory_Separator$="/"
	CompilerEndSelect
	path+#Directory_Separator$
	While CountString(path, #Directory_Separator$+#Directory_Separator$)
		path=ReplaceString(path, #Directory_Separator$+#Directory_Separator$, #Directory_Separator$)
	Wend
	Protected this.s=GetCurrentDirectory(), exist=1, n, new.s=this, temp.s
	While SetCurrentDirectory(StringField(path, exist, #Directory_Separator$))
		exist+1
	Wend
	For n=exist To CountString(path, #Directory_Separator$)
		temp=StringField(path, n, #Directory_Separator$)
		If Not (CreateDirectory(temp) And SetCurrentDirectory(temp))
			DeleteDirectory(new, "", #PB_FileSystem_Recursive)
			SetCurrentDirectory(this)
			ProcedureReturn 0
		EndIf
		new+#Directory_Separator$+temp
	Next
	SetCurrentDirectory(this)
	ProcedureReturn 1
EndProcedure

Debug CreatePath("C:\Test\PrograMMe\\pure basic")
Sol auch auf Linux gehen, kann's aber nicht testen.

Arbeitsweise:
Zunächst hänge ich ein OS-spezifisches Backslash an und fange dann alle doppelten (Back)Slashes ab :wink:
Dann speichere ich den aktuellen Pfad von GetCurrentDirectory() in einer Variablen um ihn am Ende wiederherzustellen.
Danach wechsle ich so weit in den Pfad hinein, wie es nur geht, mittels SetCurrentDirectory(). Das ist das selbe, als würde ich in einer Eingabeaufforderung folgendes eingeben:

Code: Alles auswählen

> C:
> cd "programme"
> cd "pureBasic"
Und schon bin ich im Ordner "C:\Programme\PureBasic\".

Kann ich nicht tiefer in den Pfad wechseln weiß ich: "Aha, das Verzeichnis gibt's noch nicht, ich muss es erstellen. Von da an wechsle ich immer 2 Befehle ab: CreateDirectory() zum Erstellen des Verzeichnisses und SetCurrentDirectory(), um in das soeben erstelle Verzeichnis zu wechseln.
Laufwerk C: gibt's ja schon, dann würde es in der Eingabeauffoerdung so aussehen:

Code: Alles auswählen

> C:
> mdir "Programme"
> cd "Programme"
> mdir "PureBasic"
> cd "pureBasic"
Geht das immer so in Ordnung, wird die Prozedur 1 zurückgeben und den aktuellen Pfad "Workingdirectory) zurücksetzen, ansonsten wird der Pfad zurückgesetzt und 0 zurückgegeben. Ihr erinnert euch: Ich speichere zu Anfang das "CurrentDir", um es nach Abschluss der Operation wiederherzustellen.
Sollte die Prozedur fehlschlagen, werden alle bis dahin erstellen Ordner gelöscht.



Verbesserungen erwünscht! :allright:


// Edit: Ich habe nicht extra groß geschrieben, das ist ein Forumsbug, offensichtlich wenn man > innerhalb der [ code ] Tags benutzt... :freak:

ja, ist ein forenbug - workaround eingefügt - mach nen zeilenumbruch am ende des code/quote blocks - Kaeru fecit
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
al90
Beiträge: 1101
Registriert: 06.01.2005 23:15
Kontaktdaten:

Beitrag von al90 »

AND51 hat geschrieben:Kann ich nicht tiefer in den Pfad wechseln weiß ich: "Aha, das Verzeichnis gibt's noch nicht, ich muss es erstellen. Von da an wechsle ich immer 2 Befehle ab: CreateDirectory() zum Erstellen des Verzeichnisses und SetCurrentDirectory(), um in das soeben erstelle Verzeichnis zu wechseln.
Alles vielzu umständlich. Du machst dir mehr arbeit als eigentlich nötig ist.
Lies einfach nur jedes SubDir aus, hänge es an dem gesammten Pfad an,
und mache ein CreateDirectory(). Falls es fehlschlägt, nimmt das OS es dir
nicht übel und übergibt nur andere rückgabewerte. (False oder True)
Aber auch diese muss du nicht abfragen. Führe die SubDir-Addition/MkDir
operation einfach bis zum ende durch und überprüfe erst dann die existents
des kompletten pfades. Das Ergebniss dann auswerten und mittels
ProcedureReturn zurückgeben. Get/SetCurenntDirectory() ist überflüssig,
brauchst du also nicht mehr. Auch das abfragen auf doppel Slashes halte
ich für etwas weit hergeholt. Gibt der Anwender es doppelt ein, ist es einfach
nur eine unfähigkeit des Anwenders. Wieso in aller Welt sollte das eigene programm
das verhindern ? :?

Was das auslesen der SubDirs betrifft; Das kann man machen wie man will.
Entweder z.b. über Mid() so wie ich es gemacht habe, oder eben über StringField().
Vielmehr sollte man aber auch nicht machen. Würden andere Programme auch nicht. :wink:
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

> Führe die SubDir-Addition/MkDir operation einfach bis zum ende durch und überprüfe erst dann die existents des kompletten pfades.
Oh Mann, du hast Recht mein Freund! :o
Der Schnupfen hat im Augenblick des Codens wohl doch überhand genommen... :coderselixir:

> Auch das abfragen auf doppel Slashes halte ich für etwas weit hergeholt.
Ursprünglich hatte ich das nur als Scherz gedacht, diese 3 Zeilen einzufügen, aber als ich dann sah, dass es z. B. bei Xaby großen ANklang fand, habe ich es einfach mal übernommen.
Es stimmt schon, ich denke mal nicht, dass einer extra zwei SLahes hintereinander eingibt, aber IMHO sollte man auf solche Fälle gefasst sein, zum Beispiel, wenn ich einen Pfad habe, der bereits einen Bachslash am Ende anthalt und ich dann aus Versehen noch "\System" dranhänge.
Das ist aber Ansichtssache und ist wirklich jedem selbst überlassen.

> Was das auslesen der SubDirs betrifft
Richtig. Ich persönlich würde aber StringField() bevorzugen... Das ist mein Lieblingsbefehl! :D
Außerdem kann ich mir sicher sein, dass ich mich nicht mit Mid() verhasple, warum auch immer.

> Vielmehr sollte man aber auch nicht machen.
Was gäbe es denn noch zu machen? Ich wüsste nichts...

> Würden andere Programme auch nicht.
Nanana! Ein Programm ist wie eine Bewerbung bei McDonalds, du willst in der Masse der Anbieter doch auffallen und die Kunden/Benutzer sollen doch gerade dein Programm nutzen, oder? :allright:

> :wink:
:)
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
al90
Beiträge: 1101
Registriert: 06.01.2005 23:15
Kontaktdaten:

Beitrag von al90 »

AND51 hat geschrieben:zum Beispiel, wenn ich einen Pfad habe, der bereits einen Bachslash am Ende anthalt und ich dann aus Versehen noch "\System" dranhänge.
Das ist natürlich was anderes. Das mache ich auch immer. Aber auch NUR dort.
Alles andere wäre humbug.
Richtig. Ich persönlich würde aber StringField() bevorzugen... Das ist mein Lieblingsbefehl! :D
Ich benutze Mid() aus gewohnheit. Vor 25 Jahren (C64) gabs leider nicht
sowas schönes wie StringField() :lol:
Was gäbe es denn noch zu machen? Ich wüsste nichts...
Damit bezog ich mich auf die "\" abfragen innerhalb des strings u.s.w.
Nanana! Ein Programm ist wie eine Bewerbung bei McDonalds, du willst in der Masse der Anbieter doch auffallen [...]
"Auffallen" ist gut. Aber wenn schon dann im positiven sinne. :lol: :allright:
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

> Alles andere wäre humbug.
Ja, aber gib mal bei Installern wie InstallSchild oder hier dieses..., argh, wie heißt es noch gleich? Nullsoft? Gib dort mal bewusst zwei Slashes ein, ich habs zwar nicht getestet, aber ich wette mit dir, dass der es ohne zu Knurren annimmt.
Und sowas schreibt der dir dann in die Registry oder sonstwohin. Also möglich ist es - aber eben sehr unwahrscheinlich.

> Ich benutze Mid() aus gewohnheit. Vor 25 Jahren (C64) gabs leider nicht sowas schönes wie StringField()
Eben drum benutz ich's. Bin zwar boch nicht so lange dabei, aber aus anderen Sprachen (JS, Delphi, QBasic) kenne ich das auch nicht.
Mid'st du noch oder StringField'st du schon? :mrgreen:
Ich empfehle dir das nur wärmstebns, denn wie gesagt du verhaspelst dich nicht mit deinen Längenangaben, brauchst dich um das Schneiden nicht kümmern und brauchst keine For-Schleifen, etc.

> "Auffallen" ist gut. Aber wenn schon dann im positiven sinne.
Natürlich! Nicht so wie hier beschrieben: http://www.s-a-ve.com/faq/10regeln.htm :mrgreen:
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
al90
Beiträge: 1101
Registriert: 06.01.2005 23:15
Kontaktdaten:

Beitrag von al90 »

AND51 hat geschrieben:argh, wie heißt es noch gleich? Nullsoft?
Wise InstallManager? InnoSetup? ClickTeam's-Installer ? :mrgreen:
Gib dort mal bewusst zwei Slashes ein, ich habs zwar nicht getestet, aber ich wette mit dir, dass der es ohne zu Knurren annimmt.
Und sowas schreibt der dir dann in die Registry oder sonstwohin. Also möglich ist es - aber eben sehr unwahrscheinlich.
Eben. Und genau aus diesem grund macht sich niemand die mühe sowas
abzufragen. (Abgesehen vom letzten Char des Strings) Wer Installer
benutzt, sollte auch intelligent genug sein zu wissen, was man eingeben muss.
Mid'st du noch oder StringField'st du schon? :mrgreen:
Eigentlich beides. Nur vergesse ich des öfteren das es StringField gibt.
Ist die gewohnheit halt. :mrgreen:
und brauchst keine For-Schleifen, etc.
Das ist nicht ganz richtig. Man braucht zwar nicht soviel schnibbeln wie bei Mid(),
aber ganz ohne For/Next-Schleifen geht's dann doch nicht.
Natürlich! Nicht so wie hier beschrieben: http://www.s-a-ve.com/faq/10regeln.htm :mrgreen:
Gut! :lol: :allright:
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

StringField durchsucht den String immer von vorne, Mid() sollte schneller
sein, bzw. mit pointern wirds dann wirklich schnell. Allerdings ist Geschwin-
igkeit oftmals bei solchen Sachen eher unwichtig.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
wolle212
Beiträge: 31
Registriert: 23.04.2005 21:39
Wohnort: Leipzig
Kontaktdaten:

Beitrag von wolle212 »

ts-soft hat geschrieben:Unter Windows:

Code: Alles auswählen

MakeSureDirectoryPathExists_(path.s)
:mrgreen:
:allright:

Bin jetzt grade über den Thread gestolpert, weil CopyFile nicht das tat, was ich wollte. Ich bin zwar nicht der Windows-API-Fan, aber dem Spaghettimonster sei dank, dass manche Dinge auch einfach sein können. Nennt mich vermessen, aber ist es zu viel verlangt, dass CopyFile() auch Pfade verarbeiten kann, bzw. dass CreateDirectory auch eine lange Kette von nicht existierenden Unterordnern erzeugen kann? :freak: Müsste man glatt mal an Fred weiterleiten ... ^^
Es gibt 10 Arten von Menschen: Jene, die das Binärsystem verstehen und jene, bei denen das nicht der Fall ist.

PB_4.20
WinXP_Pro_x32_SP3
Antworten