Comment savoir si un fichier existe ?
Il existe divers moyens de tester la présence d'un fichier. Le premier, très souvent utilisé, mais sans doutes à tort est l'emploi de la fonction Dir : Function FileExists(ByVal sFileName As String) As Boolean If Len(Dir(sFileName)) = 0 Then FileExists = ((GetAttr(sFileName) And vbDirectory) = 0) End If End Function Cette solution, si elle a le mérite d'être assez simple à mettre en oeuvre a quelques inconvénients majeurs : - Sa vitesse est faible en comparaison avec la méthode GetAttr, décrite plus loin : elle met en moyenne trois fois plus de temps à s'exécuter !
- En outre, vous ne pouvez pas l'utiliser alors que vous listez les fichiers d'un répertoire. Vous devrez dès lors vous passer de la vérification d'existence des fichiers dans les fonctions pouvant être appelées lors de l'énumération, ce qui peut constituer une forme de trou de sécurité.
La seconde procédure n'utilise que GetAttr : Function FileExists(ByVal sFileName As String) As Boolean On Error Resume Next FileExists = ((GetAttr(sFileName) And vbDirectory) = 0) End Function Cette solution, qui est encore une fois entièrement codée en Visual Basic sans additifs ne présente pas les désagréments de la précédente. Toutefois, il est possible de discuter longtemps sur la considération que l'on donne à une erreur, simple nombre informant de l'état ou réel problème dans le code. Ainsi, certains puristes refuseront l'utilisation de cette fonction, droit leur en appartient! Pour palier à ce dernier problème, il est possible d'utiliser les APIs de recherche de fichiers, FindFirstFile et FindClose: Private Const MAX_PATH = 260 Private Const FILE_ATTRIBUTE_DIRECTORY = &H10 Private Const INVALID_HANDLE_VALUE = -1
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 Declare Function FindFirstFile _ Lib "kernel32" _ Alias "FindFirstFileA" _ ( _ ByVal lpFileName As String, _ lpFindFileData As WIN32_FIND_DATA _ ) _ As Long Private Declare Function FindClose _ Lib "kernel32" _ ( _ ByVal hFindFile As Long _ ) _ As Long
Function FileExists( ByVal sFileName As String) As Boolean Dim hFind As Long, udtFindData As WIN32_FIND_DATA hFind = FindFirstFile(sFileName, udtFindData) If hFind <> INVALID_HANDLE_VALUE Then FileExists = (udtFindData.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY) = 0 FindClose hFind End If End Function Cette méthode nécessite moult déclarations mais ne génère plus d'erreurs. Il est aussi possible d'utiliser l'intéressante fonction de l'API Windows : PathFileExists. Cette fonction retourne une valeur booléenne indiquant si un objet du file system (fichier ou répertoire) est valide ou non. Importante limitation : cette fonction ne fonctionne que sur le File System Local, ou sur un disque distant assigné à une lettre de lecteur. Un chemin tel que 'Z:\tmp\toto.xt' est correct, alors que l'UNC '\\parsifal\somedir\somefile.txt' ne fonctionnera pas. Private Declare Function PathFileExists Lib "shlwapi.dll" Alias "PathFileExistsA" (ByVal pszPath As String) As Long
If PathFileExists(sFileName) Then MsgBox "l'objet " & sFileName & " est un réperoire ou fichier valide" End If Une dernière solution est d'utiliser le FSO (FileSystemObject) qui permet une gestion complète et simple des fichiers, dossiers et disques. Cependant, nous vous recommandons la lecture des désavantages du FSO avant de vous engager dans cette piste. |