web-dev-qa-db-fra.com

Comment vérifiez-vous si un répertoire existe sous Windows en C?

Question

Dans une application Windows C, je souhaite valider un paramètre passé dans une fonction pour m'assurer que le chemin spécifié existe. *

Comment vérifiez-vous si un répertoire existe sous Windows en C?

* Je comprends que vous pouvez entrer dans des conditions de course où entre le moment où vous vérifiez l'existence et le moment où vous utilisez le chemin, il n'existe plus, mais je peux y faire face.

Contexte supplémentaire

Savoir explicitement qu'un répertoire existe ou n'existe pas peut devenir délicat lorsque des autorisations entrent en jeu. Il est possible qu'en tentant de déterminer si le répertoire existe, le processus ne dispose pas des autorisations d'accès au répertoire ou à un répertoire parent. C'est OK pour mes besoins. Si le répertoire n'existe pas OR je ne peux pas y accéder, les deux sont traités comme un échec de chemin invalide dans mon application, donc je n'ai pas besoin de différencier. (Virtual) points bonus si votre solution prévoit cette distinction.

Toute solution dans le langage C, la bibliothèque d'exécution C ou l'API Win32 va bien, mais idéalement, je voudrais m'en tenir aux bibliothèques qui sont généralement chargées (par exemple kernel32, user32, etc.) et éviter les solutions qui impliquent le chargement de bibliothèques non standard (comme PathFileExists dans Shlwapi.dll). Encore une fois, des points bonus (virtuels) si votre solution est multiplateforme.

En relation

Comment pouvons-nous vérifier si un fichier existe ou non en utilisant le programme Win32?

61
Zach Burlingame

Faites quelque chose comme ça:

BOOL DirectoryExists(LPCTSTR szPath)
{
  DWORD dwAttrib = GetFileAttributes(szPath);

  return (dwAttrib != INVALID_FILE_ATTRIBUTES && 
         (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}

La méthode GetFileAttributes () est incluse dans Kernel32.dll.

87
retrodrone

Voici une solution totalement indépendante de la plateforme (en utilisant la bibliothèque C standard)

Edit: Pour que cela compile sous Linux, remplacez <io.h> avec <unistd.h> et _access avec access. Pour une véritable solution indépendante de la plateforme, utilisez la bibliothèque Boost FileSystem.

#include <io.h>     // For access().
#include <sys/types.h>  // For stat().
#include <sys/stat.h>   // For stat().

bool DirectoryExists( const char* absolutePath ){

    if( _access( absolutePath, 0 ) == 0 ){

        struct stat status;
        stat( absolutePath, &status );

        return (status.st_mode & S_IFDIR) != 0;
    }
    return false;
}

Une implémentation spécifique à Windows qui prend en charge les versions MBCS et UNICODE:

#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <tchar.h>

BOOL directory_exists( LPCTSTR absolutePath )
{
  if( _taccess_s( absolutePath, 0 ) == 0 )
  {
    struct _stat status;
    _tstat( absolutePath, &status );
    return (status.st_mode & S_IFDIR) != 0;
  }

  return FALSE;
}
23
dario_ramos

Si la liaison avec l'API Shell Lightweight (shlwapi.dll) vous convient, vous pouvez utiliser la fonction PathIsDirectory .

9
Simon Mourier

Une autre option est la fonction Shell PathFileExists ()

documentation PathFileExists ()

Cette fonction "détermine si un chemin d'accès à un objet du système de fichiers tel qu'un fichier ou un répertoire est valide."

4
Greg