Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Dateipfad in Variable speichern? (https://www.delphipraxis.net/211658-dateipfad-variable-speichern.html)

Kevinpptx 19. Okt 2022 11:05

Dateipfad in Variable speichern?
 
Hallo,

Ich versuche gerade einen Dateipfad in einer Variable zu speichern, für ein Programm, welches ungefähr folgendem Testprogramm entspricht:

Delphi-Quellcode:
procedure Test();

begin

  p1String := 'H:\testend\profil1';
  p2String := 'H:\testend\profil2';
  p3String := 'H:\testend\profil3';
  p4String := 'H:\testend\profil4';

  profil1 := true;     // Diese true bzw. false Werte würden je nach Benutzerauswahl automatisch auf true / false gesetzt werden
  profil2 := false;
  profil3 := false;
  profil4 := false;

  if profil1 then begin
    if not DirectoryExists(p1String) then begin
      CreateDir(p1String);
      //andere Sachen machen, auch den Pfad p1String verwenden
    end;
  end;

  if profil2 then begin
    if not DirectoryExists(p2String) then begin
      CreateDir(p2String);
      //andere Sachen machen, auch den Pfad p2tring verwenden
    end;
  end;

  if profil3 then begin
    if not DirectoryExists(p3String) then begin
      CreateDir(p3String);
      //andere Sachen machen, auch den Pfad p3String verwenden
    end;
  end;

  if profil4 then begin
    if not DirectoryExists(p4String) then begin
      CreateDir(p4String);
      //andere Sachen machen, auch den Pfad p4String verwenden
    end;
  end;


end;
Die Pfade in einem String zu speichern funktioniert nicht und um Internet habe ich nichts dazu gefunden. Hat jemand eine Idee, wie man das umsetzen könnte, gerne auch anders? Die 4 Pfade sind immer gleich, deswegen möchte ich vermeiden, dass man als Anwender selbst einen Pfad spezifizieren muss.

Danke schonmal für eure Antworten :)

Edit: Doch, es funktioniert, ich weiß nicht, warum es gerade nicht funktioniert hat. Schreibt gerne als Antwort noch Vorschläge, diese Umsetzung zu optimieren :)

Kevinpptx 19. Okt 2022 11:19

AW: Dateipfad in Variable speichern?
 
Hallo nochmal, ich weiß nicht warum, aber es funktioniert jetzt. Nutzt diesen Thread aber gerne, falls es eine optimalere Umsetzung gibt, ich bin offen für Vorschläge.

Jasocul 19. Okt 2022 12:15

AW: Dateipfad in Variable speichern?
 
Ich gehe mal davon aus, dass immer nur ein Profil aktiv sein kann. Da würde ich sofort auf einen Enumerator zurückgreifen, um die 4 if..then rauszuschmeißen und durch ein case ersetzen. Bei einem case wird sofort nach dem richtigen Fall der Rest übersprungen. Bei deiner Variante werden immer alle Profile geprüft.
Diesen Teil:
Delphi-Quellcode:
    if not DirectoryExists(p1String) then begin
      CreateDir(p1String);
würde ich in eine Methode auslagern, da immer das gleiche, nur mit anderen Werten gemacht wird. Am besten sollte es eine Function sein, damit du im Fehlerfall reagieren kannst.
Das würde insgesamt etwa so aussehen:
Delphi-Quellcode:
type
  tProfiles = (UnknownProfile, p1, p2, p3, p4);

const
  p1String = 'H:\testend\profil1';
  p2String = 'H:\testend\profil2';
  p3String = 'H:\testend\profil3';
  p4String = 'H:\testend\profil4';

function IsDirectoryOK(const ADirName: String);
begin
   Result := DirectoryExists(ADirName);
   if not Result then begin
     try
      CreateDir(ADirName);
     except
      Result := false;
     end;
   end;
end;

procedure Test(Profil: tProfiles);
begin
  case Profil of
   p1: begin
     if IsDirectoryOK(p1String) then begin
     //andere Sachen machen, auch den Pfad p1String verwenden
     end;
   end;
   p2: begin
     if IsDirectoryOK(p2String) then begin
     //andere Sachen machen, auch den Pfad p2String verwenden
     end;
   end;
   p3: begin
     if IsDirectoryOK(p3String) then begin
     //andere Sachen machen, auch den Pfad p3String verwenden
     end;
   end;
   p4: begin
     if IsDirectoryOK(p4String) then begin
     //andere Sachen machen, auch den Pfad p4String verwenden
     end;
   end
   else
     showmessage('ungültiges Profil gewählt');
  end;
end;
Das ist ungeprüft, da ich gerade kein Delphi zur Hand habe.

KodeZwerg 19. Okt 2022 12:29

AW: Dateipfad in Variable speichern?
 
Ich würde das CreateDir mit ForceDirectories austauschen (und es auch als Prüfung verwenden)
also
Delphi-Quellcode:
  case Profil of
   p1: begin
     if ForceDirectories(p1String) then begin
     //andere Sachen machen, auch den Pfad p1String verwenden
     end;
   end;
//etc...

KodeZwerg 19. Okt 2022 12:42

AW: Dateipfad in Variable speichern?
 
Delphi-Quellcode:
const
  DirArray: array[0..3] of String = ('H:\testend\profil1', 'H:\testend\profil2', 'H:\testend\profil3', 'H:\testend\profil4');

function DirCheck(const AIndex: Integer): Boolean;
begin
  if ((AIndex < Low(DirArray)) or (AIndex > High(DirArray))) then
    Exit(False);
  Result := ForceDirectories(DirArray[AIndex]);
end;
Vielleicht so in der Art... ?

Jasocul 19. Okt 2022 12:53

AW: Dateipfad in Variable speichern?
 
Bin mir gerade nicht sicher was ForceDirectory macht, falls das Verzeichnis bereits existiert. Es kann dann ja nicht erzeugt werden. Ist das Ergebnis dann auch False? Dann wäre die Kapselung in einer Function, wie ich es vorgeschlagen habe, besser. Abgesehen davon muss man berücksichtigen, das ForceDirectory immer einen voll qualifizierten Pfad benötigt (steht auch in der Doku). Das ist im Beispiel des TE zwar gegeben, sollte aber beachtet werden.
Wenn die Bedingungen erfüllt sind, würde ich auch ForceDirectory bevorzugen. Ein Try..Except ist dennoch sinnvoll, falls mal ein Leerstring übergeben wird, da ForceDirectory in dem Fall eine Exception bringt. Aber es kann auch sein, dass DirectoryExists dann auch schon einen Fehler produziert. Müsste man mal prüfen. :wink:

Jasocul 19. Okt 2022 12:57

AW: Dateipfad in Variable speichern?
 
Zitat:

Zitat von KodeZwerg (Beitrag 1513462)
Delphi-Quellcode:
const
  DirArray: array[0..3] of String = ('H:\testend\profil1', 'H:\testend\profil2', 'H:\testend\profil3', 'H:\testend\profil4');

function DirCheck(const AIndex: Integer): Boolean;
begin
  if ((AIndex < Low(DirArray)) or (AIndex > High(DirArray))) then
    Exit(False);
  Result := ForceDirectories(DirArray[AIndex]);
end;
Vielleicht so in der Art... ?

Ich hasse unnötige Exits (In diesem Fall noch übersichtlich, aber ich habe schon schlechte Erfahrungen bei größeren Methoden damit gemacht):
Delphi-Quellcode:
const
  DirArray: array[0..3] of String = ('H:\testend\profil1', 'H:\testend\profil2', 'H:\testend\profil3', 'H:\testend\profil4');

function DirCheck(const AIndex: Integer): Boolean;
begin
  Result := ((AIndex >= Low(DirArray)) and (AIndex <= High(DirArray)));
  if Result then
    Result := ForceDirectories(DirArray[AIndex]);
end;

KodeZwerg 19. Okt 2022 13:02

AW: Dateipfad in Variable speichern?
 
Zitat:

Zitat von Jasocul (Beitrag 1513464)
Bin mir gerade nicht sicher was ForceDirectory macht, falls das Verzeichnis bereits existiert. Es kann dann ja nicht erzeugt werden. Ist das Ergebnis dann auch False? Dann wäre die Kapselung in einer Function, wie ich es vorgeschlagen habe, besser. Abgesehen davon muss man berücksichtigen, das ForceDirectory immer einen voll qualifizierten Pfad benötigt (steht auch in der Doku). Das ist im Beispiel des TE zwar gegeben, sollte aber beachtet werden.
Wenn die Bedingungen erfüllt sind, würde ich auch ForceDirectory bevorzugen. Ein Try..Except ist dennoch sinnvoll, falls mal ein Leerstring übergeben wird, da ForceDirectory in dem Fall eine Exception bringt. Aber es kann auch sein, dass DirectoryExists dann auch schon einen Fehler produziert. Müsste man mal prüfen. :wink:

Es gibt True zurück wenn es den Pfad erstellen konnte bzw wenn der Pfad bereits existiert.

Kevinpptx 19. Okt 2022 13:34

AW: Dateipfad in Variable speichern?
 
Danke für die ganzen Ideen! Ich konnte einiges umsetzen :)

Harry Stahl 19. Okt 2022 14:41

AW: Dateipfad in Variable speichern?
 
Alternativ könnte man das auch so machen (Unit System.IOUtils wird benötigt):

Delphi-Quellcode:
type
  TProfiles = (p1, p2, p3, p4);

var
  Basepath : String = 'H:\testend\profil';

  SelectedPath: String;

var
  Form26: TForm26;

implementation

{$R *.dfm}

function ExistsOrCreateDir (APath: String): Boolean;
begin
    try
    if not TDirectory.Exists(APath) then begin
      System.IOUtils.TDirectory.CreateDirectory(APath);
    end;
  finally
    Result := TDirectory.Exists (APath);
  end;
end;


procedure TForm26.Button1Click(Sender: TObject);
begin
  SelectedPath := BasePath + Succ (Ord (p1)).tostring;
  if ExistsOrCreateDir (SelectedPath) then begin
    //...
  end;
end;
Die Verwendung von TDirectory ist Plattformübergreifend und erhöht somit die Wiederverwendbarkeit des Codes.
Intern verwendet TDirectory ForceDirectories, wenn erforderlich und schmeißt eine Exception mit einem entsprechenden veständlichen Hinweis, wenn z.B. ein nicht existierendes Laufwerk im Basepath verwendet wird.

Mit dieser Variante kann man Basepath leicht abändern und das ganze flexibel auf einem anderen Laufwerk einsetzen.

Je nach dem, könnte man auch eine eigene Klasse bilden (hängt vom sonstigen Code ab).

Edit: Kurz nach dem Post fiel mir auf, dass Du ja noch den ausgewählten Path für weitere Aktionen brauchst, daher hier noch etwas abgeändert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz