Wat is de beste manier om te controleren of een bestand bestaat in C?

Is er een betere manier dan gewoon proberen het bestand te openen?

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

Antwoord 1, autoriteit 100%

Zoek de functie access()op, te vinden in unistd.h. U kunt uw functie vervangen door

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

U kunt ook R_OK, W_OKen X_OKgebruiken in plaats van F_OKom te controleren op leesrechten , schrijftoestemming, en uitvoertoestemming (respectievelijk) in plaats van bestaan, en u kunt OR een van hen samen (dwz controleer op zowel lees-enschrijftoestemming met behulp van R_OK|W_OK)

Update: Houd er rekening mee dat u in Windows W_OKniet kunt gebruiken om betrouwbaar te testen op schrijfrechten, aangezien de toegangsfunctie geen rekening houdt met DACL’s. access( fname, W_OK )retourneert mogelijk 0 (succes) omdat het bestand niet het kenmerk alleen-lezen heeft, maar u hebt mogelijk nog steeds geen toestemming om naar het bestand te schrijven.


Antwoord 2, autoriteit 19%

Gebruik statals volgt:

#include <sys/stat.h>   // stat
#include <stdbool.h>    // bool type
bool file_exists (char *filename) {
  struct stat   buffer;   
  return (stat (filename, &buffer) == 0);
}

en noem het zo:

#include <stdio.h>      // printf
int main(int ac, char **av) {
    if (ac != 2)
        return 1;
    if (file_exists(av[1]))
        printf("%s exists\n", av[1]);
    else
        printf("%s does not exist\n", av[1]);
    return 0;
}

Antwoord 3, autoriteit 14%

Als je wilt controleren of een bestand bestaat, is dat meestal omdat je dat bestand wilt makenals dat niet het geval is. Graeme Perrows antwoordis goed als je dat bestand nietwilt maken, maar het is kwetsbaar voor een raceconditie als je dat wel doet: een ander proces zou het bestand tussen jou kunnen maken om te controleren of het bestaat, en jij daadwerkelijk openen om ernaar te schrijven. (Niet lachen… dit zou slechtegevolgen voor de beveiliging kunnen hebben als het aangemaakte bestand een symbolische link was!)

Als je het bestaan wilt controleren enhet bestand wilt maken als het niet bestaat, atomischzodat er geen racecondities zijn, gebruik dan dit:

p>

#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 */
}

Antwoord 4, autoriteit 5%

Ja. Gebruik stat(). Zie de man-pagina voorstat(2).

stat()zal mislukken als het bestand niet bestaat, anders slagen. Als het bestaat, maar je hebt geen toegang tot de map waar het bestaat, het zal ook falen, maar in dat geval zal elke methode mislukken (hoe kun je de inhoud van een map inspecteren die je misschien niet kunt zien volgens toegangsrechten? Eenvoudig, je kunt het niet).

Oh, zoals iemand anders vermeld, kunt u ook access()gebruiken. Ik geef de voorkeur <stat(), alsof het bestand bestaat, ontvangt het onmiddellijk veel nuttige informatie (wanneer was het voor het laatst bijgewerkt, hoe groot is het, eigenaar en / of groep die het bestand bezit, Toegang tot machtigingen, enzovoort).


5, Autoriteit 2%

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
        }

6

U kunt de functie RealPath () gebruiken.

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

7

Ik denk dat toegang () Functie, die is gevonden in unistd.his een goede keuze voor Linux(u kunt stat ook).

U kunt het als volgt gebruiken:

#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);
    }
}

en u krijgt de volgende uitvoer:

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

Other episodes