Quelle est la meilleure façon de vérifier si un fichier existe dans C? (plateforme croisée)

Y a-t-il un meilleur moyen que d’essayer simplement d’ouvrir le fichier?

int exists(const char *fname) { FILE *file; if ((file = fopen(fname, "r"))) { fclose(file); return 1; } return 0; } 

Recherchez la fonction access() , trouvée dans unistd.h . Vous pouvez remplacer votre fonction par

 if( access( fname, F_OK ) != -1 ) { // file exists } else { // file doesn't exist } 

Vous pouvez également utiliser R_OK , W_OK et X_OK à la place de F_OK pour vérifier les permissions de lecture, d’écriture et d’exécution (respectivement) plutôt que l’existence, et vous pouvez OU les utiliser ensemble (c.-à-d. en utilisant R_OK|W_OK )

Mise à jour : Notez que sous Windows, vous ne pouvez pas utiliser W_OK pour tester de manière fiable les droits d’écriture, car la fonction d’access ne prend pas en compte les DACL. access( fname, W_OK ) peut renvoyer 0 (succès) car l’atsortingbut en lecture seule n’est pas défini pour le fichier, mais vous ne pouvez toujours pas être autorisé à écrire dans le fichier.

Utilisez stat comme ceci:

 int file_exist (char *filename) { struct stat buffer; return (stat (filename, &buffer) == 0); } 

et appelez comme ceci:

 if (file_exist ("myfile.txt")) { printf ("It exists\n"); } 

Habituellement, lorsque vous souhaitez vérifier si un fichier existe, c’est parce que vous souhaitez créer ce fichier s’il ne l’est pas. La réponse de Graeme Perrow est bonne si vous ne voulez pas créer ce fichier, mais il est vulnérable à une situation de concurrence si vous le faites: un autre processus pourrait créer le fichier entre vous pour vérifier s’il existe et l’ouvrir pour l’écrire . (Ne riez pas … cela pourrait avoir de mauvaises implications pour la sécurité si le fichier créé était un lien symbolique!)

Si vous voulez vérifier l’existence et créer le fichier s’il n’existe pas, de manière atomique pour qu’il n’y ait pas de conditions de concurrence, utilisez ceci:

 #include  #include  fd = open(pathname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR); if (fd < 0) { /* failure */ if (errno == EEXIST) { /* the file already existed */ ... } } else { /* now you can use the file */ } 

Oui. Utilisez stat (). Voir le lien

Stat échouera si le fichier n’existe pas, sinon la plupart du temps probablement réussir. S’il existe, mais que vous n’avez pas access en lecture au répertoire où il existe, il échouera également, mais dans ce cas, toute méthode échouera (comment inspecter le contenu d’un répertoire que vous ne pouvez pas voir en fonction des droits d’access? Simplement, vous ne pouvez pas).

Oh, comme quelqu’un d’autre l’a mentionné, vous pouvez également utiliser access (). Cependant, je préfère stat (), comme si le fichier existe, il me donnera immédiatement beaucoup d’informations utiles (date de la dernière mise à jour, taille, propriétaire et / ou groupe propriétaire du fichier, permissions d’access, etc.) .

À partir de l’aide de Visual C ++, j’aurais tendance à aller avec

 /* ACCESS.C: This example uses _access to check the * file named "ACCESS.C" to see if it exists and if * writing is allowed. */ #include  #include  #include  void main( void ) { /* Check for existence */ if( (_access( "ACCESS.C", 0 )) != -1 ) { printf( "File ACCESS.C exists\n" ); /* Check for write permission */ if( (_access( "ACCESS.C", 2 )) != -1 ) printf( "File ACCESS.C has write permission\n" ); } } 

Il convient également de noter les valeurs de mode de _accesss (const char * path, int mode )

00 Existence seulement

02 autorisation d’écriture

04 autorisation de lecture

06 Autorisation de lecture et d’écriture

Comme votre fopen pouvait échouer dans des situations où le fichier existait mais ne pouvait pas être ouvert comme demandé.

Edit: Lisez simplement le post de Mecki. stat () ressemble à une manière plus simple de procéder. Ho hum.

 FILE *file; if((file = fopen("sample.txt","r"))!=NULL) { // file exists fclose(file); } else { //File not found, no memory leak since 'file' == NULL //fclose(file) would cause an error } 

Je pense que la fonction access () , qui se trouve dans unistd.h est un bon choix pour Linux (vous pouvez aussi utiliser stat ).

Vous pouvez l’utiliser comme ceci:

 #include  #include  #include void fileCheck(const char *fileName); int main (void) { char *fileName = "/etc/sudoers"; fileCheck(fileName); return 0; } void fileCheck(const char *fileName){ if(!access(fileName, F_OK )){ printf("The File %s\t was Found\n",fileName); }else{ printf("The File %s\t not Found\n",fileName); } if(!access(fileName, R_OK )){ printf("The File %s\t can be read\n",fileName); }else{ printf("The File %s\t cannot be read\n",fileName); } if(!access( fileName, W_OK )){ printf("The File %s\t it can be Edited\n",fileName); }else{ printf("The File %s\t it cannot be Edited\n",fileName); } if(!access( fileName, X_OK )){ printf("The File %s\t is an Executable\n",fileName); }else{ printf("The File %s\t is not an Executable\n",fileName); } } 

Et vous obtenez le résultat suivant:

 The File /etc/sudoers was Found The File /etc/sudoers cannot be read The File /etc/sudoers it cannot be Edited The File /etc/sudoers is not an Executable 

Vous pouvez utiliser la fonction realpath ().

 resolved_file = realpath(file_path, NULL); if (!resolved_keyfile) { /*File dosn't exists*/ perror(keyfile); return -1; }