Die Community zu .NET und Classic VB.
Menü

Existiert eine Datei oder ein Ordner?

 von 

Einleitung  

In dieser Ausgabe wollen wir verschiedene Möglichkeiten betrachten, mit denen man feststellen kann, ob eine Datei oder ein Ordner auf dem System existiert. Für diesen Zweck existieren in der Funktionsbibliothek von Visual Basic leider keine eigenen Funktionen. Deshalb muss eine Lösung auf anderem Wege gesucht werden. Die vorgestellten Möglichkeiten zur Existenzprüfung dienen nicht dazu, festzustellen, ob auf eine Datei oder einen Ordner zugegriffen werden kann, sondern können lediglich dazu benutzt werden, zu überprüfen, ob eine Datei oder ein Ordner existiert.

Neben den vorgestellten Methoden gibt es noch eine Menge anderer Möglichkeiten. Weitere Informationen zu diesem Thema finden sich im entsprechenden Artikel von Jost Schwider. An dieser Stelle sei Jost Schwider für wichtige Hinweise, die in diesen Artikel Eingang gefunden haben, gedankt. Die Kolumne wurde am 1. November 2005 auf Basis von Kommentaren ergänzt und überarbeitet.

Existenzprüfung mit Visual Basic-eigenen Funktionen  

Folgende Funktion prüft mit Visual Basic-eigenen Mitteln, ob eine Datei oder ein Ordner existiert. Dazu wird die Funktion GetAttr benutzt, die dazu dient, Attribute einer Datei oder eines Ordners zu ermitteln. Wird diese Funktion auf einen nicht existierenden Pfad angewendet, so wird ein Fehler ausgelöst. Durch On Error Resume Next wird unterbunden, dass die Anwendung mit einem Fehler beendet wird.

Private Function FileExists(ByVal FileName As String) As Boolean
    On Error Resume Next
    FileExists = Not CBool(GetAttr(FileName) And (vbDirectory Or vbVolume))
    On Error Goto 0
End Function

Private Function DirExists(ByVal DirectoryName As String) As Boolean
    On Error Resume Next
    DirExists = CBool(GetAttr(DirectoryName) And vbDirectory)
    On Error Goto 0
End Function

Listing 1: Existenzprüfung durch Ermitteln der Attribute mit Visual Basic-eigenen Funktionen

Anstelle von GetAttr im obigen Beispiel könnte auch bspw. die Funktion FileLen oder eine passende andere Dateizugriffsfunktion benutzt werden. Auf die Verwendung der Funktion Dir$ zur Existenzprüfung sollte aber dringend verzichtet werden, da diese Funktion nicht eintrittsinvariant ist. Ihre Verwendung kann zur Folge haben, dass sich anderen Programmteile nach Aufruf der Funktion zur Existenzprüfung nicht mehr wie erwartet verhalten. Im folgenden Beispiel wird in der Prozedur EnumDirs Dir$ zur Aufzählung der Unterordner eines Ordners verwendet. Wird während der Aufzählung eine auf Dir$ basierende Funktion zur Existenzprüfung eingesetzt (im Listing markiert durch ein Rufzeichen), führt dies zu unvollständigen Aufzählungsergebnissen.

Private Sub EnumDirs(ByVal Path As String)
    Dim CurrentDir As String
    CurrentDir = Dir$(Path, vbDirectory)
    Do While Len(CurrentDir) > 0
        If CurrentDir <> "." And CurrentDir <> ".." Then
            If _
                CBool(GetAttr(CombinePath(Path, CurrentDir)) And vbDirectory) _
            Then
                Debug.Print CurrentDir
            End If
        End If
        Debug.Print DirExists("C:\Programme")   ' !
        CurrentDir = Dir$
    Loop
End Sub

Private Function DirExists(ByVal Path As String) As Boolean
    DirExists = (Len(Dir$(Path, vbDirectory)) > 0)
End Function

Private Function CombinePath(ByVal Part1 As String, ByVal Part2 As String)
    CombinePath = Part1
    If Right$(CombinePath, 1) <> "\" Then
        CombinePath = CombinePath & "\"
    End If
    CombinePath = CombinePath & Part2
End Function

Listing 2: Probleme bei Verwendung der Funktion 'Dir$' zur Existenzprüfung

Existenzprüfung mit dem FileSystemObject  

Das FileSystemObject stellt eine Methode mit dem Namen FileExists bereit, die benutzt werden kann, um die Existenz einer Datei zu ermitteln. Analog dazu besitzt das Objekt eine Methode FolderExists zur Existenzbestimmung von Ordnern. Alleine zur Überprüfung der Existenz einer Datei oder eines Ordners ist das FileSystemObject jedoch überdimensioniert und das Hinzufügen der Abhängigkeit zu einem Projekt nicht gerechtfertigt. In Projekten, in denen ohnehin bereits Gebrauch von dieser Komponente gemacht wird, erweist sich diese Methode hingegen als nützlich.

Existenzprüfung mit API-Aufrufen  

Eine einfache Methode zur Existenzüberprüfung von Dateien und Ordnern stellt die Verwendung der API-Funktion GetFileAttributes dar, die ähnlich der Visual Basic-eigenen Funktion GetAttr zum Lesen von Dateiattributen dient. Anders als bei der Funktion GetAttr kann jedoch die Fehlerbehandlung zugunsten der Überprüfung des Rückgabewerts der Funktion eingespart werden.

Private Declare Function GetFileAttributes _
    Lib "kernel32.dll" _
    Alias "GetFileAttributesA" _
( _
    ByVal lpFileName As String _
) As Long

Private Const INVALID_FILE_ATTRIBUTES As Long = -1&

Private Const FILE_ATTRIBUTE_DIRECTORY As Long = &H10&

Private Function FileExists(ByVal FileName As String) As Boolean
    Dim dwAttributes As Long
    dwAttributes = GetFileAttributes(FileName)
    If dwAttributes = INVALID_FILE_ATTRIBUTES Then
        FileExists = False
    ElseIf CBool(dwAttributes And FILE_ATTRIBUTE_DIRECTORY) Then
        FileExists = False
    Else
        FileExists = True
    End If
End Function

Private Function DirExists(ByVal DirectoryName As String) As Boolean
    Dim dwAttributes As Long
    dwAttributes = GetFileAttributes(DirectoryName)
    If dwAttributes = INVALID_FILE_ATTRIBUTES Then
        DirExists = False
    ElseIf CBool(dwAttributes And FILE_ATTRIBUTE_DIRECTORY) Then
        DirExists = True
    Else
        DirExists = False
    End If
End Function

Listing 3: Existenzprüfung durch Ermitteln der Attribute mit API-Aufrufen

Eine weitere Lösung, die auf der Windows-API basiert, macht sich die Funktionen FindFirstFile und FindClose zunutze. Über die erste Funktion erhält man eine Zugriffsnummer auf die erste Datei, deren Name dem übergebenen Muster entspricht. Wenn die Zugriffsnummer gleich -1 ist, dann konnte die Datei nicht gefunden werden. Abschließend wird der Suchvorgang beendet.

Private Declare Function FindFirstFile _
    Lib "kernel32.dll" _
    Alias "FindFirstFileA" _
( _
    ByVal lpFileName As String, _
    ByRef lpFindFileData As WIN32_FIND_DATA _
) As Long
Private Declare Function FindClose Lib "kernel32.dll" ( _
    ByVal hFindFile As Long _
) As Long

Private Const INVALID_HANDLE_VALUE As Long = -1&
Private Const MAX_PATH As Long = 260&

Private Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type

Private Type WIN32_FIND_DATA
    dwFileAttributes As Long
    ftCreationTime As FILETIME
    ftLastAccessTime As FILETIME
    ftLastWriteTime As FILETIME
    nFileSizeHigh As Long
    nFileSizeLow As Long
    dwReserved0 As Long
    dwReserved1 As Long
    cFileName As String * MAX_PATH
    cAlternate As String * 14
End Type

Private Function FileExists(ByVal FileName As String) As Boolean
    Dim wfd As WIN32_FIND_DATA
    Dim hFile As Long
    hFile = FindFirstFile(FileName, wfd)
    FileExists = (hFile <> INVALID_HANDLE_VALUE)
    If hFile <> INVALID_HANDLE_VALUE Then
        Call FindClose(hFile)
    End If
End Function

Listing 4: Existenzprüfung durch Suche nach dem Dateinamen

Weiters bietet sich die API-Funktion PathFileExists aus der shlwapi.dll an. Ein Beispiel zu deren Verwendung findet sich im Tipp 0605: Path-APIs nutzen. Es ist zu beachten, dass diese Funktion nicht unter allen Versionen von Windows zur Verfügung steht.

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 19 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von XETH am 02.01.2008 um 13:40

On Local Error Resume Next macht seit vb6 keinen unterschied mehr zur variante

Kommentar von Codefreaker am 25.02.2007 um 10:49

So spart man noch je eine Zeile.
Besser:

Private Function FileExists(ByVal FileName As String) As Boolean
On Local Error Resume Next
FileExists = Not CBool(GetAttr(FileName) And (vbDirectory Or vbVolume))
End Function

Private Function DirExists(ByVal DirectoryName As String) As Boolean
On Local Error Resume Next
DirExists = CBool(GetAttr(DirectoryName) And vbDirectory)
End Function

Kommentar von Tio am 28.09.2006 um 15:24

Hey, Super, funktioniert!! Danke Philipp!

Kommentar von Philipp Stephani am 28.09.2006 um 14:49

@Tio: Dafür musst du FindFirstFile benutzen, siehe Listing 4.

Kommentar von Tio am 28.09.2006 um 14:29

Hallo,
wie ist es möglich, dass ich dem Dateinamen ein Asteriks mitgeben kann? Es geht darum, dass ich z.B. eine Datei ABC22.pdf habe, wobei ich nur auf "ABC*.pdf" prüfen will (anstelle der "22" können mehrere Zeichen folgen). Ich habe mal probehalber [Verzeichnis]\ABC*.pdf an die Funktion FileExists übergeben, aber trotz definitivem Vorhandenseins wurde sie nicht gefunden. Also geht das mit dem "*" nicht. Wie kann man das hinkriegen? Gibt es da eine andere Funktion für?

Kommentar von Philipp Stephani am 13.09.2006 um 00:09

@d1ng0d0gt0r: Wird in der Kolumne bereits behandelt (Abschnitt «Existenzprüfung mit dem FileSystemObject»).

Kommentar von d1ng0d0gt0r am 12.09.2006 um 22:08

Ich hab hier eine einfachere Funktion gefunden zum überprüfen von Dateien:

private sub command1_click()
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists("C:\test.txt") Then
msgbox "exist"
else
msgbox "not exist"
end if
end sub

Kommentar von d1ng0d0gt0r am 12.09.2006 um 22:03

Kann mir jemand sagen wie ich das anwende?

Kommentar von P. Walther am 06.07.2006 um 13:08

Ich finde das Forum einfach super,
war mir bisher eine große Hilfe.

Paul

Kommentar von S. Beil am 03.07.2006 um 18:55

Tolle und fundierte Hilfe!
Ist leider selten im Internet geworden.....

Kommentar von oest am 16.03.2006 um 13:04

Einfach toll.
Solche essentiellen Beiträge wünscht man sich.

Kommentar von Florian Rittmeier am 05.11.2005 um 08:42

Die bisher geposteten Beiträge wurde von Herfried K. Wagner in den Artikel eingearbeitet.

Gruß Florian
-------------------
Team ActiveVB

Kommentar von am 19.07.2005 um 21:20

@Sebastian:
Die Methode heißt "FolderExists".

Kommentar von Sebastian am 19.07.2005 um 15:50

Private Function ExistFolder(ByRef strPath As String) As Boolean
Dim objFSO As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
ExistFolder = objFSO.DirExists(strPath)
End Function

----------
Das FileSystemObject hat überhaupt
keine Methode namens DirExists !!!
Lediglich DriveExists.

Kommentar von Timon am 01.02.2005 um 10:05

"PathFileExist" ist auch eine gute möglichkeit!
im tipp0605 werden "PathFileExist" und noch viele andere API's für die arbeit mit pfaden erklärt.
(http://www.activevb.de/tipps/vb6tipps/tipp0605.html)

Gruss Timon

Kommentar von Jan-Marten am 07.01.2005 um 05:34

Kann man das nich auch einfach mit dem "PathFileExists" API machen??? oder arbeitet das irgentwie schlechter oder langsamer?

Hat mich nur gewundert, dass diese Lösung hier nicht gelistet ist.

mfg. Jan-Marten

Kommentar von Philipp am 11.12.2003 um 11:30

Die Existenz einer Datei kann auch leichter mittels API geprüft werden:
Declare Function PathFileExists Lib "shlwapi.dll" Alias "PathFileExistsA" (ByVal pszPath As String) As Long

Philipp

Kommentar von Recable am 16.09.2003 um 19:51

Ich finde die Kolumne sollte auch auf der Hauptpage verlinkt werden. Dieser Beitrag hat mir sehr gefallen

Kommentar von Philipp Stephani am 17.04.2003 um 20:33

Das Buch "Visual Basic Hardcore" (in der MSDN Library enthalten) bietet die API-Funktion GetFileAttributes an, die ebenfalls keinen Fehlerauslöst und einfacher als die FindFirstFile-Funktion ist.