Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi prüfen, ob es ein Ordner ist (https://www.delphipraxis.net/36803-pruefen-ob-es-ein-ordner-ist.html)

Gina 26. Dez 2004 10:36


prüfen, ob es ein Ordner ist
 
Hallo,

ich weiß, dass diese Frage in ähnlicher Form schon öfter gefallen ist. Trotzdem würde mich eins speziell interessieren:

Ich habe in einer Listbox verschiedene Pfade als Einträge drin. Manche sind Ordner und manche Dateien. Welches ist die schnellste und zugleich sicherste Methode zu prüfen, ob es sich bei dem Eintrag um einen Ordner handelt?

Vielen lieben Dank, Gina.

Matze 26. Dez 2004 10:38

Re: prüfen, ob es ein Ordner ist
 
Evtl. einfach die Dateiendung abfragen.

Daniel 26. Dez 2004 10:42

Re: prüfen, ob es ein Ordner ist
 
Ne. Ich habe Verzeichnisse, die heißen 'starteam.install' o.ä.
Du solltest Dir über Delphi-Referenz durchsuchenFindFirst() die Attribute des jeweiligen Eintrages ermitteln lassen. Bei Verzeichnissen ist dann das Flag Delphi-Referenz durchsuchenfaDirectory gesetzt. Dieser Weg sollte zuverlässig und sauber sein.

Es geht aber auch anders: Wenn Du absolut sicher bist, dass es entweder Dateien oder Verzeichnisse sind, dann prüfe mit Delphi-Referenz durchsuchenDirectoryExists(), ob ein Eintrag ein Verzeichnis ist. Wenn nein, dann muss es ja eine Datei sein.

mirage228 26. Dez 2004 10:47

Re: prüfen, ob es ein Ordner ist
 
Hi,

ich habe hier eine bzw. zwei nützliche Funktion(en) für Dich:

Delphi-Quellcode:
  function IsDirectoryA(const Dir: string): Boolean;
  var
    F: TWin32FindDataA;
    Handle: HWnd;
  begin
    Handle := FindFirstFileA(PChar(Dir), F);
    if Handle <> INVALID_HANDLE_VALUE then
    begin
      Result := ((f.dwFileAttributes and faDirectory) = faDirectory);
      Windows.FindClose(Handle);
    end else
      Result := False;
  end;

  function IsDirectory(Dir: WideString): Boolean;
  var
    F: TWin32FindDataW;
    Handle: HWnd;
  begin
    Dir := ExcludeTrailingPathDelimiter(Dir);
    if (Win32Platform <> VER_PLATFORM_WIN32_NT) then
      Result := IsDirectoryA(Dir) else
    begin
      Handle := FindFirstFileW(PWideChar(Dir), F);
      if Handle <> INVALID_HANDLE_VALUE then
      begin
        Result := ((f.dwFileAttributes and faDirectory) = faDirectory);
        Windows.FindClose(Handle);
      end else
        Result := False;
    end;
  end;
Du musst einfach immer IsDirectory() aufrufen, um abzufragen, ob das Element ein Verzeichnis ist.

mfG
mirage228

Luckie 26. Dez 2004 10:49

Re: prüfen, ob es ein Ordner ist
 
Warum nicht die entsprechende Funktion aus der Unit FileCtrl nehmen?

Daniel 26. Dez 2004 10:52

Re: prüfen, ob es ein Ordner ist
 
Zitat:

Zitat von Luckie
Warum nicht die entsprechende Funktion aus der Unit FileCtrl nehmen?

...weil es die da zum Beispiel in Delphi 2005 nicht (mehr) gibt? Ich hatte auch nach etwas in der Richtung gesucht, aber nichts mehr gefunden.

Luckie 26. Dez 2004 10:55

Re: prüfen, ob es ein Ordner ist
 
Gibt es bestimmt. Und wenn es ein .NET Programm werden soll, wäre die WinAPI Lösung von mirage auch nicht angebracht.

mirage228 26. Dez 2004 10:56

Re: prüfen, ob es ein Ordner ist
 
Zitat:

Zitat von Daniel
Zitat:

Zitat von Luckie
Warum nicht die entsprechende Funktion aus der Unit FileCtrl nehmen?

...weil es die da zum Beispiel in Delphi 2005 nicht (mehr) gibt? Ich hatte auch nach etwas in der Richtung gesucht, aber nichts mehr gefunden.

Äh, im Win32 Teil gibt es Unit noch auf jeden Fall ;). Für .NET gibt es die Directory Klasse(n) :)

Edit:
Nochmal für .NET
Delphi-Quellcode:
System.IO.Directory.Exists()
mfG
mirage228

Matze 26. Dez 2004 10:57

Re: prüfen, ob es ein Ordner ist
 
Zitat:

Zitat von Daniel
Es geht aber auch anders: Wenn Du absolut sicher bist, dass es entweder Dateien oder Verzeichnisse sind, dann prüfe mit Delphi-Referenz durchsuchenDirectoryExists(), ob ein Eintrag ein Verzeichnis ist. Wenn nein, dann muss es ja eine Datei sein.

Wenn ich aber in einem Ordner eine Datei und einen Ordner mit gleichem Dateinamen habe, kann's da auch zu Problemchen kommen.

Daniel 26. Dez 2004 10:59

Re: prüfen, ob es ein Ordner ist
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Luckie
Gibt es bestimmt.

Du kleiner Widerporst. :mrgreen: Ich hatte die Datei eben vor der Nase. Screenie im Anhang.


Vielleicht ist es aber auch einfach nur zu früh für mich.

Luckie 26. Dez 2004 11:00

Re: prüfen, ob es ein Ordner ist
 
Was macht DirectoryExists, wenn es sich um eine Datei handelt?

Daniel 26. Dez 2004 11:01

Re: prüfen, ob es ein Ordner ist
 
Ich will schwer hoffen, dass dann false zurückgeliefert wird. Schrieb ich aber auch schon oben.

Matze 26. Dez 2004 11:03

Re: prüfen, ob es ein Ordner ist
 
Zitat:

Zitat von Luckie
Was macht DirectoryExists, wenn es sich um eine Datei handelt?

Ich meinte das so

Datei: c:\Rumpelstilzchen\Feuerlöscher.jpg
Ordner: c:\Rumpelstilzchen\Feuerlöscher.jpg\ <== so kann ja auch ein Ordner heißen

Wenn der Ordner nun ohne Backslash am Ende da steht und es diese Datei auch gibt, kann man es wohl nicht unterscheiden, oder irre ich mich da? :gruebel:

Alexander 26. Dez 2004 11:08

Re: prüfen, ob es ein Ordner ist
 
Probier es aus, aber ich meine, dass es mit DirectoryExist geht.

PS: Kann es gerade selber nicht ausprobieren...

Gina 26. Dez 2004 11:14

Re: prüfen, ob es ein Ordner ist
 
Uii, so schnell kann man ja kaum mitlesen...

Mal schauen, ob ich alles entdeckt habe. Also:

Mit Dateiendung abfragen geht nicht, weil auch Dateien bei sind, die evtl keine Endung haben, aber trotzdem keine Ordner sind und umgekehrt kanns ja auch sein.

FindFirst: Bitte nicht schlagen, aber wenn ich FindFirst auf einen Ordner anwende, frage ich dann nicht den Inhalt des Ordners ab und nicht den Ordner selbst?

An DirectoryExists hatte ich auch schon gedacht, bin aber davon ausgegenagen, dass es "unsauber" sei... :oops: Aber wenn es schnell und zuverlässig ist... Werds gleich mal testen.

Bis gleich, Gina.

Luckie 26. Dez 2004 11:16

Re: prüfen, ob es ein Ordner ist
 
Zitat:

Zitat von Gina
FindFirst: Bitte nicht schlagen, aber wenn ich FindFirst auf einen Ordner anwende, frage ich dann nicht den Inhalt des Ordners ab und nicht den Ordner selbst?

Nein, entscheidet ist diese Zeile:
Delphi-Quellcode:
Result := ((f.dwFileAttributes and faDirectory) = faDirectory);
Dort wird geprüft, ob die gefundene Datei ein Ordner ist oder nicht.

Gina 26. Dez 2004 12:09

Re: prüfen, ob es ein Ordner ist
 
Also ich kann unter XP keine Datei mit dem gleichen Namen wie ein im selben Verzeichnis befindlichen Ordner erstellen... Ist das immer so? Dann würde DirectoryExists funktionieren. Es wird auf jeden Fall false zurückgegeben, wenn eine Datei ohne Dateiendung geprüft wird...

Das wäre dann wohl das Kürzeste, oder?

Thx, Gina.

PS: Was ist eigentlich "dwFileAttributes" ? Ist das aus D2005? :roll:

Christian Seehase 26. Dez 2004 13:23

Re: prüfen, ob es ein Ordner ist
 
Moin Zusammen,

warum beisst ihr euch eigentlich alle an DirectoryExists fest?
Wenn sicher ist, dass es sich um eine Datei oder ein Verzeichnis handelt, könnte man einfach mit FileExists prüfen, ob es eine Datei ist.

BTW:
Meiner Erfahrung nach funktioniert DirectoryExists unter Windows ME nicht sauber, zumindest die Version aus D5.

Gina 26. Dez 2004 14:04

Re: prüfen, ob es ein Ordner ist
 
Hi, hier will doch keiner beißen :wink:

Es geht lediglich um eine schnelle und sichere Methode, um zu prüfen, ob es ein Ordner ist. Ich sehe da keinen großen Unterschied, ob ich nun FileExist oder DirectoryExist nehme. Ob nun eine davon verläßlicher ist, kann ich leider nicht beurteilen. Die Frage ist, ob eins der beiden ausreicht.

"Wenn sicher ist, dass es sich um eine Datei oder ein Verzeichnis handelt..."

Was könnte es denn sonst noch sein? :gruebel: Ein Laufwerk wird als Ordner erkannt, was für meine Zwecke ok ist...

Nochmal zu faDirectory:

Kann ich das zur auch Prüfung benutzen, ohne vorher FindFirst anzuwenden? Ich bin immernoch der Meinung, dass mit FindFirst der Inhalt des angegebenen Pfades nach Ordnern geprüft wird, nicht der Pfad selbst. Ansonsten hab ich Euch falsch verstanden. :oops: Vielleicht hilft mir dann ein kleines Beispiel weiter, wie es gemeint sein soll? Das wäre supi.

Vielen lieben Dank, Gina.

Christian Seehase 26. Dez 2004 16:09

Re: prüfen, ob es ein Ordner ist
 
Moin Gina,

Zitat:

Zitat von Gina
Kann ich das zur auch Prüfung benutzen, ohne vorher FindFirst anzuwenden?

Nein kannst Du nicht, denn womit willst Du es denn vergleichen? ;-)

Zitat:

Zitat von Gina
Ich bin immernoch der Meinung, dass mit FindFirst der Inhalt des angegebenen Pfades nach Ordnern geprüft wird, nicht der Pfad selbst.

FindFirst liefert Dir immer das erste Auftauchen des angegebenen Pfades zurück, unabhängig davon, ob es sich um eine Datei oder ein Verzeichnis handelt, natürlich vorausgesetzt, dass der angegebene Pfad überhaupt existiert.
Wenn jetzt der Pfad keine Wildcards (*,?) enthält wird exakt der angebene Pfad gesucht.

Ich habe die Erfahrung gemacht, dass es am Besten ist als Attributflags faAnyFile anzugeben, und anschliessend auf Directory usw. zu prüfen.

Für Deinen Anwendungsfall dürfte allerdings die unmittelbare Prüfung mittels DirectoryExists/FileExists am meisten Sinn machen.

Gina 26. Dez 2004 16:28

Re: prüfen, ob es ein Ordner ist
 
Hmm, dann mache ich irgendwas falsch, denn wenn ich auf faDirectory prüfe, liefert er mir false zurück, obwohl ich definitiv einen Ordner prüfe...

Kannst du mir mal please die genaue Formulierung posten?

Tausend Dank, Gina.

Christian Seehase 26. Dez 2004 17:56

Re: prüfen, ob es ein Ordner ist
 
Moin Gina,

zeig' doch mal, wie Du es machst.

Gina 26. Dez 2004 18:24

Re: prüfen, ob es ein Ordner ist
 
Also ich hab das unter anderem so probiert:

Delphi-Quellcode:
if (FindFirst(Datei,faDirectory,SR) = 0) then
if ((SR.Attr and faDirectory) = faDirectory) then
:gruebel: Gina.

mirage228 26. Dez 2004 18:29

Re: prüfen, ob es ein Ordner ist
 
Zitat:

Zitat von Gina
Also ich hab das unter anderem so probiert:

Delphi-Quellcode:
if (FindFirst(Datei,faDirectory,SR) = 0) then
if ((SR.Attr and faDirectory) = faDirectory) then
:gruebel: Gina.

Hi,

hast Du es schonmal mit meiner Variante probiert? Die sollte eigentlich funktioniern...

mfG
mirage228

Gina 26. Dez 2004 18:40

Re: prüfen, ob es ein Ordner ist
 
Ne, sorry. Hab nur Delphi 6. Und bei deinem Code kenne ich einiges nicht. z.B. das: 'dwFileAttributes'

Außerdem sollte es so kurz wie möglich sein, weil es in einer Schleife aufgerufen wird. Das kann dann schon mal mehrere tausend Mal sein...

Gina.

mirage228 26. Dez 2004 18:44

Re: prüfen, ob es ein Ordner ist
 
Zitat:

Zitat von Gina
Ne, sorry. Hab nur Delphi 6. Und bei deinem Code kenne ich einiges nicht. z.B. das: 'dwFileAttributes'

Außerdem sollte es so kurz wie möglich sein, weil es in einer Schleife aufgerufen wird. Das kann dann schon mal mehrere tausend Mal sein...

Gina.

Sicher?

Ich habe es eben unter Delphi 6 Personal getestet und den Code in ein neues Projekt kopiert. Es lief einwandfrei.

Du musst lediglich die Units Windows (TWin32FindDataW und TWin32FindDataA, etc.) und SysUtils (ExcludeTrailingBackslash) in Deiner Uses-Liste haben.

Die Länge sollte hier keine allzu große Rolle spielen. Im Notfall kannst du ja nur die IsDirectoryA() Funktion benutzen. Die ist relativ kurz, kann aber nur mit ANSI-String Pfaden umgehen.

mfG
mirage228

Christian Seehase 26. Dez 2004 19:12

Re: prüfen, ob es ein Ordner ist
 
Moin Gina,

probier's mal so:

Code:
if (FindFirst(Datei,[color=red][b]faAnyFile[/b][/color],SR) = 0) then
[EDIT]
Mirages Source per Copy&Paste in D6 kopiert: Kompiliert anstandslos.
An D6 kann's nicht liegen. ;-)
[/EDIT]

Gina 27. Dez 2004 11:02

Re: prüfen, ob es ein Ordner ist
 
Zitat:

Zitat von Christian Seehase
probier's mal so:

Code:
if (FindFirst(Datei,[color=red][b]faAnyFile[/b][/color],SR) = 0) then

Bringt leider genau das gleiche Ergebnis... :cry: Vielleicht haben wir uns auch mißverstanden.
Nehmen wir mal an, in Datei steht 'F:\test\utest\'. Ich möchte jetzt wissen, ob utest ein Ordner ist oder eine Datei. Wenn ich jetzt FindFirst anwende, schaut er in F:\test\utest rein und sucht dort nach dem ersten Eintrag und prüft, ob es ein Ordner oder eine Datei ist. Entsprechend sieht auch das Ergebnis im Debug-Modus aus. Und genau so verstehe ich auch die Funktionsweise von Findfirst.

[EDIT:] Ok, jetzt hab ichs kapiert. :oops: Es hängt alles an dem letzten Backslash. Wenn der da ist, sucht er in dem Verzeichnis und wenn er weg ist sucht er das Verzeichnis... Ist schon erstaunlich, was so ein kleines Zeichen bewirken kann. Sorry für die Verwirrung. Jetzt muss ich mir nur überlegen, ob ich es so mache, weil ich dann immer zuerst den Backslash wegnehmen müßte und ihn danach wieder ransetzen müßte...

Vielen lieben Dank für Eure Geduld. Jetzt muss ich nur noch rausfinden, was am schnellsten geht und dann ist meine Frage erledigt... :wink: [/EDIT]

Zitat:

Zitat von Christian Seehase
[EDIT]
Mirages Source per Copy&Paste in D6 kopiert: Kompiliert anstandslos.
An D6 kann's nicht liegen. ;-)
[/EDIT]

Sorry, ich hab ja gesagt, dass ich ihn nicht probiert hatte, weil ich erst wissen wollte was das für Befehle sind... :oops: Da sie mir völlig unbekannt waren und die Delphi-Hilfe auch nix dazu sagen konnte, dachte ich sie seinen aus D2005...

Inzwischen hab ich ihn natürlich getestet. Er funktioniert auch einwandfrei. Ich werd mal schauen, ob ich das etwas abkürzen kann, weil so wie er ist, braucht er etwa doppelt so lange wie eine Prüfung mit DirectoryExists, wobei mir das eigentlich sagt, dass DirectoryExists ziemlich lahm zu sein scheint...

Vielen lieben Dank für die Hilfe, Gina.

Gina 27. Dez 2004 12:56

Re: prüfen, ob es ein Ordner ist
 
Soo...

Von der Schnelligkeit her nimmt sich FindFirst, IsDirectory von Mirage und auch FileExists gar nichts.

Einzig und alleine DirectoryExists ist immer noch schneller. Warum auch immer. Das bezieht sich natürlich nur auf mein System und meine Delphi-Version und kann mit einer anderen Konfiguration ganz anders aussehen.

Ich würde mich daher erstmal für DirectoryExists entscheiden.

Ist irgendjemandem noch etwas eingefallen, wo damit Probleme auftauchen könnten? Wo mir also eventuell nicht das gewünschte Ergebnis angezeigt werden könnte?

Thx, Gina.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:31 Uhr.

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