web-dev-qa-db-fra.com

Vérification de l'existence d'un répertoire sous Unix (appel système)

Je ne trouve pas de solution à mon problème en ligne.

Je voudrais appeler une fonction sous Unix, passer le chemin d'un répertoire et savoir s'il existe. opendir() renvoie une erreur si un répertoire n'existe pas, mais mon objectif n'est pas d'ouvrir, de vérifier l'erreur, de la fermer si aucune erreur, mais plutôt de vérifier simplement si un fichier est un répertoire ou non.

Existe-t-il un moyen pratique de le faire, s'il vous plaît?

49
Jary

Il existe deux fonctions pertinentes sur les systèmes POSIX: stat () et lstat () . Ceux-ci sont utilisés pour savoir si un nom de chemin fait référence à un objet réel auquel vous êtes autorisé à accéder et, dans l'affirmative, les données renvoyées vous indiquent de quel type d'objet il s'agit. La différence entre stat() et lstat() est que si le nom que vous donnez est un lien symbolique, stat() suit le lien symbolique (ou les liens s'ils sont chaînés ensemble) et rend compte de l'objet à la fin de la chaîne de liens, tandis que lstat() rend compte du lien symbolique lui-même.

#include <sys/stat.h>

struct stat sb;

if (stat(pathname, &sb) == 0 && S_ISDIR(sb.st_mode))
{
    ...it is a directory...
}

Si la fonction indique qu'elle a réussi, vous utilisez la macro S_ISDIR () de <sys/stat.h> pour déterminer si le fichier est réellement un répertoire.

Vous pouvez également rechercher d'autres types de fichiers à l'aide d'autres S_IS* macros:

  • S_ISDIR - répertoire
  • S_ISREG - fichier régulier
  • S_ISCHR - périphérique de caractères
  • S_ISBLK - bloquer le périphérique
  • S_ISFIFO - FIFO
  • S_ISLNK - lien symbolique
  • S_ISSOCK - prise

(Certains systèmes fournissent également quelques autres types de fichiers; S_ISDOOR est disponible sur Solaris, par exemple.)

105
Jonathan Leffler

Vous pouvez utiliser l'appel système stat en lui passant le nom du répertoire comme premier argument. Si le répertoire existe, un 0 est renvoyé sinon -1 est renvoyé et errno sera défini sur ENOENT

MODIFIER:

Si la valeur de retour est 0 vous auriez besoin d'une vérification supplémentaire pour vous assurer que l'argument est bien un répertoire et non un fichier/symlink/char fichier spécial/blk fichier spécial/FIFO. Vous pouvez utiliser le st_mode champ du stat structure pour cela.

5
codaddict

Si vous parlez d'un Shell, il y a une bonne SO réponse ici. Pour résumer cette réponse:

if [ -d "$DIRECTORY" ]; then
    # Control will enter here if $DIRECTORY exists
fi

Si vous parlez de l'intérieur d'un programme C, vous pouvez utiliser stat() :

{
    struct stat st;
    if(stat("/tmp",&st) == 0)
        printf(" /tmp is present\n");
}
3
Bryan

Vous pouvez utiliser test -d

3
chigley

Un autre moyen simple serait:

int check(unsigned const char type) {
    if(type == DT_REG)
        return 1;
    if(type == DT_DIR)
        return 0;
    return -1;
}

Vous pouvez ensuite passer struct dirent * d_type de l'objet à la fonction check.

Si la vérification renvoie 1, ce chemin pointe vers un fichier normal.

Si la vérification renvoie 0, ce chemin pointe vers un répertoire.

Sinon, ce n'est ni un fichier, ni un répertoire (il peut s'agir d'un Block Device/Symbolic Link, etc.)

1
Aishwary Dewangan

Testé et fonctionne bien:

int file_exist (char *filename)
{
    char s[200];
    sprintf(s, "test -e %s", filename);
    if (system(s) == 0){
        return 1;
    }else{
        return 0;
    }
}
1
Mehrdad Seyrafi

Si vous ne vous souciez pas vraiment du type de cet objet de système de fichiers, access (nom, F_OK) vérifie l'existence de quelque chose avec ce nom. Si vous devez vous assurer qu'il s'agit bien du répertoire, utilisez stat () et vérifiez le type avec la macro S_ISDIR ().

1
blaze

Je pense que la fonction stat peut faire ce que vous voulez (je ne l'ai pas testé pour les répertoires). En C++, vous pouvez également utiliser la bibliothèque boost :: filesystem.

0
neodelphi