94 votes

Moyen portable de vérifier si un répertoire existe [Windows/Linux, C]

Je voudrais vérifier si un répertoire donné existe. Je sais comment le faire sous Windows :

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

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

et Linux :

DIR* dir = opendir("mydir");
if (dir)
{
    /* Directory exists. */
    closedir(dir);
}
else if (ENOENT == errno)
{
    /* Directory does not exist. */
}
else
{
    /* opendir() failed for some other reason. */
}

Mais j'ai besoin d'un moyen portable pour le faire Existe-t-il un moyen de vérifier si un répertoire existe quel que soit le système d'exploitation que j'utilise ? Peut-être la bibliothèque standard C ?

Je sais que je peux utiliser les directives des préprocesseurs et appeler ces fonctions sur différents systèmes d'exploitation, mais ce n'est pas la solution que je recherche.

JE ME RETROUVE AVEC CECI, DU MOINS POUR L'INSTANT :

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>

int dirExists(const char *path)
{
    struct stat info;

    if(stat( path, &info ) != 0)
        return 0;
    else if(info.st_mode & S_IFDIR)
        return 1;
    else
        return 0;
}

int main(int argc, char **argv)
{
    const char *path = "./TEST/";
    printf("%d\n", dirExists(path));
    return 0;
}

139voto

Ingo Leonhardt Points 4020

stat() fonctionne sous Linux, UNIX et Windows :

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

struct stat info;

if( stat( pathname, &info ) != 0 )
    printf( "cannot access %s\n", pathname );
else if( info.st_mode & S_IFDIR )  // S_ISDIR() doesn't exist on my windows 
    printf( "%s is a directory\n", pathname );
else
    printf( "%s is no directory\n", pathname );

26voto

Ivan Nikitin Points 1200

Avec C++17, vous pouvez utiliser std::filesystem::is_directory fonction ( https://en.cppreference.com/w/cpp/filesystem/is_directory ). Il accepte un std::filesystem::path qui peut être construit avec un chemin unicode.

9voto

Adam Parsons Points 21

Comme j'ai trouvé que la réponse approuvée ci-dessus manque de clarté et que l'op fournit une solution incorrecte qu'il/elle utilisera. J'espère donc que l'exemple ci-dessous aidera les autres. La solution est également plus ou moins portable.

/******************************************************************************
 * Checks to see if a directory exists. Note: This method only checks the
 * existence of the full path AND if path leaf is a dir.
 *
 * @return  >0 if dir exists AND is a dir,
 *           0 if dir does not exist OR exists but not a dir,
 *          <0 if an error occurred (errno is also set)
 *****************************************************************************/
int dirExists(const char* const path)
{
    struct stat info;

    int statRC = stat( path, &info );
    if( statRC != 0 )
    {
        if (errno == ENOENT)  { return 0; } // something along the path does not exist
        if (errno == ENOTDIR) { return 0; } // something in path prefix is not a dir
        return -1;
    }

    return ( info.st_mode & S_IFDIR ) ? 1 : 0;
}

6voto

Tony The Lion Points 28208

Utilice boost::filesystem qui vous donnera un moyen portable de faire ce genre de choses et de faire abstraction de tous les détails gênants pour vous.

2voto

Mali Points 2507

Vous pouvez utiliser le GTK glib pour faire abstraction du système d'exploitation.

glib fournit un g_dir_open() qui devrait faire l'affaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X