Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Gibts Alternativen zu File-/DirectoryExists? (https://www.delphipraxis.net/160377-gibts-alternativen-zu-file-directoryexists.html)

Jumpy 10. Mai 2011 14:29

Delphi-Version: 2010

Gibts Alternativen zu File-/DirectoryExists?
 
Hallo zusammen,

ich möchte eine Funktion/Klasse/Irgendwas (eine Art Generallösung )entwickeln, mit denen man prüfen kann, ob eine Datei, ein Pfad, ein Laufwerk existiert und habe noch keine Idee wie. Kenne dazu bisher auch nur die oben genannten Funktionen. Gibt es da weitere? Auch wäre schön, wenn Berechtigungsfehler erkannt werden.

Wenn eine Datei mit Pfad usw. übergeben wird, soll geprüft werden können, ob die Datei existiert. Aber auch, falls nicht, ob denn wenigsten der Pfad schon existiert oder das Laufwerk (gemappt ist).
DirectoryExists liefert False wenn es eine Datei übergeben bekommt. Könnte man natürlich ExtractFilepath vorschalten.

Es kann aber auch mal nur der Pfad geprüft werden. Dann verkürzt mir das ExtractFilePath den Pfad und verfälscht so ggf. das Ergebnis.

Wenn denn Pfad/Datei existieren, sollen auch die Rechte abgeklopft werden. Vor allem, darf das Programm bzw. wahrsch. der eingeloggte User in dem Pfad schreiben/löschen...


-------
Hintergrund ist halt, das bestimmte Verarbeitungen (beim Start) prüfen können sollen, ob Sie ihre Aufgabe erfüllen können und falls nicht gar nicht erst richtig starten. Hier halt: "Sind die Verzeichnisse die ich brauche verfügbar".
(Ein anderer Zweig dieser Checker-Klasse( -oder Funktion?), wenn man so will könnte auf die Verfügbarkeit oder die Version anderer Programme prüfen, z.B. ist Excel vorhanden, wenn ich später mit Ole darauf zugreifen will, oder welches OS,...).

Hoffe die Richtung in die die Frage geht ist ein bißchen klar geworden. Da ich selbst noch nicht zu 100% weiß wie das aussehen soll entschuldige ich mich für die schwammigkeit. Es geht mir halt auch um Ideen oder Anregungen.

Bernhard Geyer 10. Mai 2011 14:35

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Versuch im verzeichnis eine Datei mit schreibrechten zu öffne bzw. die Datei mit schreibrechten zu öffnen.
Anschließend holst du dir mittels GetlastError den Fehlergrund falls nicht klappt.

Sir Rufo 10. Mai 2011 15:07

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Die Alternative baut man sich selber (die Fingerübung zum Feierabend)
Delphi-Quellcode:
type
  TFileDirExistsRet = ( fdeNo, fdeFile, fdeDir );

function FileDirExists( const FileOrDir : string ) : TFileDirExistsRet;
begin
  if DirectoryExists( FileOrDir )
  then
    Result := fdeDir
  else if FileExists( FileOrDir )
  then
    Result := fdeFile
  else
    Result := fdeNo;
end;

Stevie 10. Mai 2011 16:54

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Da als Delphi Version 2010 angegeben ist: zieh dir mal die IOUtils.pas rein

Alternativ die JclFileUtils.pas aus der JCL.

himitsu 10. Mai 2011 17:36

AW: Gibts Alternativen zu File-/DirectoryExists?
 
und noch 'ne Fingerüberung nach dem Feierabend

Delphi-Quellcode:
type
  TFileDirExistsRet = (fdeNo, fdeFile, fdeDir);

function FileDirExists(const FileOrDir: String): TFileDirExistsRet;
var
  FindFileData: TWIN32FindData;
begin
  FindFileData.dwFileAttributes := INVALID_FILE_ATTRIBUTES;
  Windows.FindClose(FindFirstFile(PChar(FileOrDir), FindFileData));
  if FindFileData.dwFileAttributes = INVALID_FILE_ATTRIBUTES then
    Result := fdeNo
  else if FindFileData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
    Result := fdeFile
  else
    Result := fdeDir;
end;

// oder

function FileDirExists(const FileOrDir: String): Boolean;
var
  FindFileData: TWIN32FindData;
begin
  FindFileData.dwFileAttributes := INVALID_FILE_ATTRIBUTES;
  Windows.FindClose(FindFirstFile(PChar(FileOrDir), FindFileData));
  Result := FindFileData.dwFileAttributes = INVALID_FILE_ATTRIBUTES;
end;

Sir Rufo 10. Mai 2011 20:58

AW: Gibts Alternativen zu File-/DirectoryExists?
 
@himitsu
Nur meinen Code kann man auf Anhieb begreifen :stupid:

Satty67 10. Mai 2011 21:05

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Zumindest die kurze Variante geht noch kürzer (Ok, hab' geschaut woher die SysUtils Funktionen die Infos holen):
Delphi-Quellcode:
function FileDirExists(s: String): Boolean;
begin
  Result := GetFileAttributes(PChar(s)) <> $FFFFFFFF;
end;
Result kann man natürlich noch auswerten für eine differenzierte Rückgabe, aber dann ist es auch nicht mehr kürzer.

Jumpy 11. Mai 2011 13:24

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Hallo und vielen Dank. Im nächste frag ich immer kurz vor Feierabend, wenn eure Finger dann so locker sitzen:-D.

Zum Problem: Die Funktion braucht ja mehr als nur eine Boolche Rückgabe, deswegen ist die Anregung mit dem Record oder ist das eine Enumeration

Delphi-Quellcode:
type
  TFileDirExistsRet = ( fdeNo, fdeFile, fdeDir );
schonmal die wertvollste. Natürlich auch die Umsetzungsvorschläge.

Konkret muss ich mir dazu noch klar werden, was ich genau will. Ich denke da an sowas, wo mehrere Rückgabewerte möglich sind, z.B. wenn Filexists dann ja auch DirectoryExists. Im ObjectInspector gibts ja so Dinge. Heißen die dann Sets? Wenn ich dann so Fragen würde:

Delphi-Quellcode:
if fdeFile in FileDirExists(MeinPfadoderDatei)
Das ist doch auch das, wo man die Dinge mit AND und OR verknüpft. War doch vor kurzem auch so ein Thread dazu. Such ich gleich mal.

himitsu 11. Mai 2011 13:45

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Delphi-Quellcode:
type
  TEnum = ( x, y, z );
  TSet1 = TEnum;

  TSet2 = set of ( x, y, z );

  TRecord = record
    a: Integer;
    b: String;
  end;
Enum = enthält mehrere Werte, aber jeweils immer nur Einen gleichzeitig
Set = kann mehrere Werte gleichzeitig aufnehmen (oder Keinen)
Record = mehrere Variablen in einem

Ein Boolean ist quasi ebenfalls ein Enumerator, mit zwei Werten.
Delphi-Quellcode:
type Boolean = (False, True);


mit SET
Delphi-Quellcode:
if fdeFile in FileDirExists(MeinPfadoderDatei) then
.
Delphi-Quellcode:
if FileDirExists(MeinPfadoderDatei) = [fdeFile] then
.
Delphi-Quellcode:
if FileDirExists(MeinPfadoderDatei) = [fdeFile, fdeDir] then
.
und ENUM
Delphi-Quellcode:
if FileDirExists(MeinPfadoderDatei) = fdeFile then
.

Jumpy 11. Mai 2011 14:03

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Danke himitsu für die Zusammenfassung, dann ist das glaub ich "set" was ich meinte und benutzen werde.

Was ist dann aber das mit dem AND und OR, wo man den Elementen die Werte 1,2,4,8,16 usw. gibt, so dass man mit binärer Logik da arbeiten kann? Ist das eine spezielle Form des Sets?

DeddyH 11. Mai 2011 14:04

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Das ist meist einfach eine Zahl.

Jumpy 11. Mai 2011 15:49

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Mein Feierabendstand für heute :-D.
Will jetzt noch auf Laufwerk testen. Gibts was um das Laufwerk aus einem Pfad zu ziehen? Kann ich notfalls auch selber bauen, indem ich nach dem Doppelpunkt suche, denk ich mal.
Vorausgesetzt es ist kein UNC Pfad. Was mach ich aber dann? Woher weiß ich wo bei einem UNC Pfad das "Laufwerk" aufhört und die Verzeichnisse anfangen?

"\\server_abc\farm_2\Reports\Kundenname\2010_1 2"
ist gleich / kann gleich sein
"R:\Kundenname\2010_12"

Delphi-Quellcode:
unit uCheck;

interface

uses StrUtils, SysUtils;

type
  TFileDirExistsRet = set of (fdeFile, fdeDir, fdeShortDir, fdeLW);

function FileDirExists( const FileOrDir : string ) : TFileDirExistsRet;
function HasExtension(const Filename : string) : Boolean;

implementation

function HasExtension(const Filename : string) : Boolean;
begin
  if Pos('.',Filename)>0 then Result:=true
  else Result := false;
end;

function IsUNCPath(const Filename : string) : Boolean;
begin
  if Copy(Filename,1,2)='\\' then Result:=true
  else Result := false;
end;

function FileDirExists( const FileOrDir : string ) : TFileDirExistsRet;
var Path : String;
begin
  Result:=[];
  Path:=ExtractFilePath(FileOrDir);

  if FileExists(FileOrDir) then
    Result:=[fdeFile, fdeDir, fdeShortDir, fdeLW]
  else
    begin
    if HasExtension(FileOrDir) then
      begin
      if DirectoryExists(Path) then
        Result:=[fdeDir, fdeShortDir, fdeLW]
      else
        begin
        if DirectoryExists(ExtractFilepath(Path)) then
          Result:=[fdeShortDir, fdeLW]
        else
          begin
            //Laufwerk prüfen, was wenn UNC?
          end;
        end
      end
    else
      begin
      if DirectoryExists(FileOrDir) then
        Result:=[fdeDir, fdeShortDir, fdeLW]
      else
        begin
        if DirectoryExists(Path) then
          Result:=[fdeShortDir, fdeLW]
        else
          begin
            //Laufwerk prüfen, was wenn UNC?
          end;
        end
      end
    end;
end;

end.

DeddyH 11. Mai 2011 15:55

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Ein UNC-Pfad besitzt nun einmal kein Laufwerk, da kannst Du auch nichts prüfen. Du könntest höchstens nachsehen, ob auf Deinem Rechner ein Laufwerk gegen eine Freigabe des Rechners, auf den der UNC-Pfad zeigt, gemappt ist.

Jumpy 11. Mai 2011 20:59

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Hab ich fast befürchtet. UNC-Pfade geben wir meist an, wenn unsicher ist, ob für den User das Laufwerk überhaupt gemappt ist, z.B. bei Jobs die Batchmäßig auf Servern laufen. Allerdings kam mit gerade die Idee, das ich ja eine Liste ablegen könnte mit allen UNC-"Laufwerken". Danke.

Jumpy 12. Mai 2011 08:33

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Guten morgen zusammen,

hier die vorerst fertige Version (wenn keinem mehr was dran auffällt) was ich ändern sollte.
Hab mir alle Funktionen rund um Pfade und Files in der Hilfe angeschaut. Dies hat zu einem Umbau
der HasExtension-Funktion geführt und der Erkenntnis, dass ich mir das Laufwerk mit ExtractFileDrive aus dem Pfad holen kann, wobei auch im Falles eines UNC-Pfades was brauchbares rauskommt.

Delphi-Quellcode:
unit uCheck;

interface

uses StrUtils, SysUtils;

type
  TFileDirExistsRet = set of (fdeFile, fdeDir, fdeShortDir, fdeLW, fdeUNC);

function FileDirExists( const FileOrDir : string ) : TFileDirExistsRet;
function HasExtension(const Filename : string) : Boolean;

implementation

function HasExtension(const Filename : string) : Boolean;
begin
  if ExtractFileExt(Filename)<>'' then Result:=true
  else Result := false;
end;

function IsUNCPath(const Filename : string) : Boolean;
begin
  if Copy(Filename,1,2)='\\' then Result:=true
  else Result := false;
end;

function FileDirExists( const FileOrDir : string ) : TFileDirExistsRet;
var
  Path : String;
begin
  Result:=[];
  Path:=ExtractFilePath(FileOrDir);
  if FileExists(FileOrDir) then
    Result:=[fdeFile, fdeDir, fdeShortDir, fdeLW]
  else
    begin
    if HasExtension(FileOrDir) then
      begin
      if DirectoryExists(Path) then
        Result:=[fdeDir, fdeShortDir, fdeLW]
      else
        begin
        if DirectoryExists(ExtractFilepath(Path)) then
          Result:=[fdeShortDir, fdeLW]
        else
          begin
            if DirectoryExists(ExtractFileDrive(FileOrDir)) then
              Result:=[fdeLW]
          end;
        end
      end
    else
      begin
      if DirectoryExists(FileOrDir) then
        Result:=[fdeDir, fdeShortDir, fdeLW]
      else
        begin
        if DirectoryExists(Path) then
          Result:=[fdeShortDir, fdeLW]
        else
          begin
            if DirectoryExists(ExtractFileDrive(FileOrDir)) then
              Result:=[fdeLW]
          end;
        end
      end
    end;

  //Festetllen ob UNC-Pfad
  if IsUNCPath(FileOrDir) then
    Result:=Result+[fdeUNC]
end;

end.

Jumpy 12. Mai 2011 09:29

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Mach mal einen Doppelpost statt eines Edits, weil ich im obigen Zusammenhang noch eine andere Frage habe. Ich habe in Excel eine ähnliche Checker-Klasse gebaut. Darin gab es eine Funktion, die den Status des Laufwerkes (eines Pfades) geprüft hat:

Code:
'VBA-Code
Private Function Laufwerkstatus(ByVal Pfad As String) As Integer
  On Error Resume Next
  If CreateObject("Scripting.FileSystemObject").GetDrive(Pfad).IsReady = True Then
    If Err.Number = 68 Then
      Laufwerkstatus = 0    'Das Laufwerk ist nicht verfügbar.
      Err.Clear
      Exit Function
    Else
      Laufwerkstatus = 1    'Das Laufwerk ist verfügbar und bereit.
      Exit Function
    End If
  Else
    Laufwerkstatus = 2      'Das Laufwerk ist verfügbar aber nicht bereit.
  End If
End Function
Es gab nämlich manchmal das Problem, dass das (Netz-)Laufwerk scheinbar da war, wurde z.B. auch im Explorer angezeigt, aber der Zugriff darauf scheiterte dann. Mal wegen Problemen mit dem Netzwerk oder dem DFS.

Frage nun, kann man das auch in Delphi nachbauen? CreateObject gibts doch in Delphi auch, oder?

Jumpy 13. Mai 2011 09:39

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Habs nach einigem googeln und rumprobieren geschafft, es nach Delphi zu portieren, hoffe ich zumindest. Es ist keine Eins-zu-Eins Umsetzung, denn ich wußte nicht, wie man in Delphi sowas wie "OnErrorResumNext und dann gib mit den Fehlercode" macht und habe das mMn entsprechend in try...except gepackt. Da ich auch nicht wußte, was die ErrCode 68 Entsprechung in Delphi ist, hab ich das auch weggelassen.
Es funktioniert aber so wie ich dachte das es soll.

Delphi-Quellcode:
procedure TMain.Test(Pfad : String);
var
  b : Boolean;
  fso : OleVariant;
begin
  try
    // b := CreateOleObject('Scripting.FileSystemObject').GetDrive(fso.GetDriveName(Pfad)).IsReady;
    // obige Zeile kompiliert nicht, umweg über fso-Variable muss scheinbar sein
    fso := CreateOleObject('Scripting.FileSystemObject');
    b := fso.GetDrive(fso.GetDriveName(Pfad)).IsReady;
    if b then showmessage('Verfügbar und bereit')
    else showmessage('Verfügbar aber nicht bereit')
  except // on e : Exception do
    showmessage('Nicht verfügbar');
  end;
end;

himitsu 13. Mai 2011 09:51

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Zitat:

Zitat von Jumpy (Beitrag 1100570)
Delphi-Quellcode:
// obige Zeile kompiliert nicht, umweg über fso-Variable muss scheinbar sein

Welches CreateOleObject nutzt du denn?
Das aus Unit OleAuto oder aus Unit ComObj?

Versuch mal Ersteres. Ansonsten könnte man noch versuchen es umzucasten.

Jumpy 13. Mai 2011 10:41

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Zitat:

Zitat von himitsu (Beitrag 1100572)
Welches CreateOleObject nutzt du denn?
Das aus Unit OleAuto oder aus Unit ComObj?

Versuch mal Ersteres. Ansonsten könnte man noch versuchen es umzucasten.

Habe ComObj benutzt. Nach deinem Tipp auch mal OleAuto ausprobiert.
(Mein Workarround funktioniert auch mit OleAuto, aber das war ja zu erwarten)

Dann die Einzeilige Variante ohne den Umweg über die fso-Variable probiert mit dem Ergebnis, dass
es schonmal ohne meckern kompiliert wird. Aber es kommt die Fehlermeldung:
Exception der Klasse EVariantInvalidOpError mit der Meldung 'Ungültige Variantenoperation' aufgetreten.

hathor 25. Jul 2013 07:58

AW: Gibts Alternativen zu File-/DirectoryExists?
 
Zitat:

Zitat von Satty67 (Beitrag 1100067)
Zumindest die kurze Variante geht noch kürzer (Ok, hab' geschaut woher die SysUtils Funktionen die Infos holen):
Delphi-Quellcode:
function FileDirExists(s: String): Boolean;
begin
  Result := GetFileAttributes(PChar(s)) <> $FFFFFFFF;
end;
Result kann man natürlich noch auswerten für eine differenzierte Rückgabe, aber dann ist es auch nicht mehr kürzer.

Ist NICHT das Gleiche wie in #5.

Funktioniert in WIN 8 nicht, aber kurzer Code in #5 geht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:37 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