Existe-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()
qui se trouve 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 droits de lecture, d'écriture et d'exécution (respectivement) plutôt que d'existence, et vous pouvez OR tous les deux ensemble (c.-à-d. vérifier les droits de lecture et permission d'écriture 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 le droit d’écriture, car la fonction d’accès ne prend pas en compte les DACL. access( fname, W_OK )
peut renvoyer 0 (succès) car l'attribut en lecture seule n'est pas défini dans le fichier, mais vous n'êtes peut-être toujours pas autorisé à l'écrire dans le fichier.
Utilisez stat comme ceci:
int file_exist (char *filename)
{
struct stat buffer;
return (stat (filename, &buffer) == 0);
}
et appelez comme ça:
if (file_exist ("myfile.txt"))
{
printf ("It exists\n");
}
Généralement, lorsque vous voulez vérifier si un fichier existe, c'est parce que vous voulez créer ce fichier s'il n'en a pas. La réponse de Graeme Perrow est bonne si vous ne pas voulez créer ce fichier, mais si vous le rencontrez, il est vulnérable à la concurrence. Un autre processus peut créer le fichier entre vous en vérifiant s'il existe, et en fait l'ouvrir pour y écrire. (Ne riez pas ... cela pourrait avoir mauvais 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, atomiquement afin qu'il n'y ait pas de race conditions, alors utilisez ceci:
#include <fcntl.h>
#include <errno.h>
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 la page de manuel de stat(2)
.
stat()
échouera si le fichier n'existe pas, sinon la plupart du temps réussiront. S'il existe, mais que vous n'avez pas d'accès en lecture au répertoire dans lequel 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'accès?). 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()
, car si le fichier existe, il me fournira immédiatement de nombreuses informations utiles (date de sa dernière mise à jour, taille, propriétaire et/ou groupe propriétaire du fichier, autorisations d'accès, etc.).
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
}
De l'aide 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 <io.h>
#include <stdio.h>
#include <stdlib.h>
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 __access(const char *path,
_int mode
_)
_:
00: Existence seulement
02: permission d'écriture
04: autorisation de lecture
06: autorisation de lecture et d'écriture
En tant que votre fopen
pourrait échouer dans des situations où le fichier existait mais ne pourrait pas être ouvert comme demandé.
Edit: Il suffit de lire le post de Mecki. stat()
ressemble à une façon plus ordonnée d'aller. Ho hum.
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 ça:
#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
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 la sortie suivante:
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;
}