Astuces de recherche...
Home
- Accueil & nouveautés
- Les newsgroups VB
- Téléchargements
- L'équipe
- Nous contacter
- Liens
Rubriques
- Toutes les questions
- Affichage & graphismes
- Algorithmique
- API
- Base de registre
- Bases de données
- Contrôles
- Date & heure
- Déploiement
- Divers
- Erreurs & problèmes
- Fichiers & dossiers
- Généralités
- Impression
- Internet & mails
- Math
- Multimédia
- Réseaux
- Structures de données
- Texte & strings
- VB .Net
- VB Script
- VBA
- Windows

Question 29

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  
      
    'Recherche du fichier spécifié  
    hFind = FindFirstFile(sFileName, udtFindData)  
      
    'On teste la réussite de la recherche  
    If hFind <> INVALID_HANDLE_VALUE Then  
        'Le fichier n'existe que s'il n'est pas un dossier  
        FileExists = (udtFindData.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY) = 0  
          
        'Fermeture du handle pour libérer la mémoire  
        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

'
' Exemple d'utilisation
'
    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.

Date de publication : 07 juillet 2002
Dernière modification : 06 mars 2008
Rubriques : Fichiers & dossiers
Mots-clés : fichier, fichiers, existence, existe, valide, PathFileExists