Relativer Pfadname

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Relativer Pfadname

Beitrag von Marc »

Ich möchte einige Bilder öffnen die in ‚ E:\MyProjects\Pdir\Library\French\French-Images‘ gespeichert sind.
Das Programm läuft aktuell auf Windows7 soll aber auch auf Linux funktionieren.

Das Arbeitsverzeichnis ist ‚ E:\MyProjects\Pdir‘.
Ist es möglich eine Datei zu öffnen nur mit der Angabe des relativen Pfads? -> Library\French\French-Images\bild.jpg
Ich muss immer den ganzen Pfad angeben.

Kompletter Pfad : E:\MyProjects\Pdir\Library\French\French-Images\bild.jpg

Um den ganzen Pfad anzugeben aber nicht den ganzen zu speichern, versuche ich diesen etwas zu zerlegen.
Es sind alle Bilder im selben Directory vorhanden. Also würde der reine Bildname zum speichern ausreichen.

1. Schritt : PathNameActDir := GetCurrentDir;
Resultat : PathNameActDir : E:\MyProjects\Pdir

Soweit so gut.

2. Schritt : PathNameImage := ExtractRelativePath(PathNameActDir,ExtractFileDir(FileNameImage));
Resultat : PathNameImage : Pdir\Library\French\French-Images

Nicht gut, Pdir habe ich jetzt zum zweiten mal. meiner Meinung nach müsste der relative Pfad‚ ‘Library\French\French-Images‘ sein?

3. FileNameImage := ExtractFileName(FileNameImage);
FileNameImage : bild.jpg

Das passt.

Gibt es einen Befehl der das ganze wieder zusammensetzt?
Ansonsten wäre meine Lösung : FileNameImage := PathNameActDir + PathNameImageD+PathDelim +FileNameImageD;
Good code comes from experience, experience comes from bad code.

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: Relativer Pfadname

Beitrag von MacWomble »

Zunächst einmal würde ich das Arbeitsverzeichnis entweder aus Application.Location oder einer (anzulegenden) INI-Datei beziehen.

Ich verwende die Variante mit der Ini-Datei, da ich die Dokumente dann auch anderswo ablegen kann.

Bei mir sieht das z.B. so aus:

[Pfade]
Dokumente=/home/ich/Dokumente/BOSS_DATA
Anbinden=/home/ich/Entwicklung/CTR-BOSS/Dokumente/Anbinden
Scans=/home/ich/Entwicklung/CTR-BOSS/Dokumente/Anbinden/Scans
Faxe=/home/ich/Entwicklung/CTR-BOSS/Dokumente/Anbinden/Faxeingang
Email=/home/ich/Entwicklung/CTR-BOSS/Dokumente/Anbinden/Posteingang
Anrufe=/home/ich/Entwicklung/CTR-BOSS/Dokumente/Anbinden/Anrufe

So habe ich aber auch die Möglichkeit, z.B. den Ordner Scans irgendwo anders abzulegen oder auch anders zu benennen.
Da ich mit Linux arbeite, verwende ich Slash statt Backslash!

Zum zusammensetzen: Das ist schon ok so wie du das machst.

Ich würde in deinem Fall die Bilder auch anders strukturieren:

Library/DE/Images/
Library/FR/Images/
Library/DE/Texte/
usw.

oder:
DE/Library/Images/
FR/Library/Images/
DE/Library/Texte/
usw.

je nach dem was genau du vor hast.

Wenn das Programm Plattformunabhängig laufen soll, musst du generell statt des / oder \ PathDelim verwenden! Bei der Ini-Datei ist dies egeal. da sie ja angepasst werden kann.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Relativer Pfadname

Beitrag von Marc »

Vielen Dank für die Antwort

Das ‚Application.Location‘ kenne ich noch nicht.
Muss ich mich schlau machen.

Es soll ein Vokabeltrainer werden.
Wenn ich 1000 Vokabeln habe mit einem Bild dazu, müsste ich, falls ich den ganzen Pfad speichere
1000 Strings à 255 Zeichen vorsehen.
Deshalb möchte ich nur einmal speichern wo die Bilder sind, und dann lediglich den Bildnamen im Record haben.
Falls ich es hinkriege will ich auf die selbe weise auch noch Audiodateien ablegen.

Das ganze Projekt soll sich nur in einem Ordner befinden. Der Uebersicht wegen.
Wie die Unterverzeichnisse heissen, da bin ich noch am experimentieren.
Aber Deine Vorschläge sehen schon mal gut aus.

Die Frage war/ist kann ich ein Bild oder eine Datei nur mit einer relativen Pfadangabe öffnen?
Falls ja könnte den kompletten Pfad ignorieren.

PathDelim verwende ich bereits.
in https://www.freepascal.org/docs-html/rt ... delim.html
steht : PathDelim refers to the system unit's DirectorySeparator constant, it is for Delphi compatibility only.
Ich verstehe das als -> besser nicht verwenden?
Möglich das es was besseres gibt? Aber OK für mich funktioniert es im Moment.

Ich meine das ‚ExtractRelativePath(FromDir,ToDir)‘ irgendwie nicht richtig funktioniert.
Vieleicht muss ich einfach mehr Tests machen.
Das überzählige Directory kriege ich auch entfernt, ist aber sicher unschön.
Good code comes from experience, experience comes from bad code.

charlytango
Beiträge: 842
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Relativer Pfadname

Beitrag von charlytango »

Mein Zugang zu der Pfadproblematik und im weiteren Sinn auch bei Programmparametern ist der, dass ein Programm zwar möglichst individuell anpassbar sein soll, aber erstmal ohne (bzw nur minimale) weitere Einstellungen funktionieren soll.
Zudem kommt dazu, dass übliche Benutzer damit ohnedies nicht umgehen können (und imho auch nicht müssen). Meine Erfahrung hat gezeigt dass Benutzer solche ini-Dateien nicht bedienen können bzw auch gnadenlos unbrauchbar machen.

Ich verwende ein Objekt das alle im Programm nötigen Pfade (und Einstellungen) zur Verfügung stellt.
Für unterschiedliche Betriebssysteme würde ich die in Lazarus bereits verfügbaren Defines verwenden (http://wiki.lazarus.freepascal.org/Platform_defines) und mal in http://wiki.lazarus.freepascal.org/Multiplatform_Programming_Guide#Cross-platform_Programming reinsehen

Code: Alles auswählen

 
FsExePath := Application.Location;
FsIniFileName :=  FsExePath + 'config.ini';
 
{$IFDEF WINDOWS]
  FsPathName01:='E:\MyProjects\Pdir';
{$ENDIF}

 
{$IFDEF LINUX]
  FsPathName01:='/MyProjects/Pdir';
{$ENDIF}



Um diese (Standard-)Einstellungen flexibler zu machen wäre es möglich die Pfade von außerhalb des Programmes mittels ini-File einzustellen.
Das Programm würde auch ohne INI File funktionieren, trotzdem hätte man notfalls eine externe Einstellmöglichkeit.

http://wiki.freepascal.org/Using_INI_Files

Code: Alles auswählen

INI := TINIFile.Create(FsIniFileName);
FsPathName01:= INI.ReadString('Section','PathName01','E:\MyProjects\Pdir');
INI.Free;


just 2cents..

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Relativer Pfadname

Beitrag von Marc »

Vielen Dank auch für die 2cents, und Entschuldigung für die späte Antwort.
Ein ini file ist nichts schlechtes. Etwas in der Art werde ich wohl noch machen aber im Programm Ordner belassen.
Danke auch für die Links.
Brauche noch etwas Zeit das alles zu bearbeiten.

Sieht so aus, als das ich die Dateiel (Bilder) nicht mit einem relativen Pfad aufrufen kann.
Kein Problem soweit. Wollte nur sicher gehen.
Good code comes from experience, experience comes from bad code.

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: Relativer Pfadname

Beitrag von MacWomble »

Ich empfehle dir im Programm Application.Location zu verwenden. Du brauchst dann in der INI nur die Pfadvervollständigung speichern.

Wenn z.B. Application.location 'c:\Programme\MeinProgramm' ergibt und du in der INI 'Bilder\DE' speicherst, kannst du das im Programm zusammensetzen und erhältst 'c:\Programme\MeinProgramm\Bilder\DE'. In diesem Fall könntest du sogar auf die INI verzichten und bleibst relativ zu deinem Programm. Jedoch ist es nicht gut Daten im Programmordner abzulegen. Zumindest dann nicht, wenn die Daten vom User verändert/erfasst werden. Hier sollte man einen Datenordner zulassen.
Und dran denken: Für die Plattformunabhängigkeit PathDelim benutzen !

Application.Location + PathDelim + 'Bilder' + PathDelim + 'DE'
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Relativer Pfadname

Beitrag von Marc »

Danke auch für diese Antwort.
Ich weiss noch nicht genau wie es sein wird am Schluss.
Ist komplett das planlose Programmieren hier, 'try and error' . :-)
Good code comes from experience, experience comes from bad code.

Antworten