Was ist der beste Weg zu überprüfen, ob eine Datei in C existiert? (plattformübergreifend)

Gibt es einen besseren Weg, als einfach nur die Datei zu öffnen?

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

Sehen Sie sich die function access() in unistd.h . Sie können Ihre function durch ersetzen

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

Sie können auch R_OK , W_OK und X_OK anstelle von F_OK , um nach Leseberechtigung, Schreibberechtigung und Ausführungsberechtigung (bzw.) und nicht nach Existenz zu F_OK , und Sie können ODER alle zusammen (dh prüfen Sie sowohl auf Lese- als auch auf Schreibberechtigung) mit R_OK|W_OK )

Update : Beachten Sie, dass Sie unter Windows nicht W_OK können, um die W_OK zuverlässig zu testen, da die Zugriffsfunktion DACLs nicht berücksichtigt. access( fname, W_OK ) kann 0 (erfolgreich) zurückgeben, da für die Datei nicht das schreibgeschützte Attribut festgelegt ist, Sie jedoch möglicherweise nicht über die Berechtigung verfügen, in die Datei zu schreiben.

Benutze stat wie folgt:

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

und nenne es so:

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

Wenn Sie überprüfen möchten, ob eine Datei vorhanden ist, möchten Sie diese Datei normalerweise erstellen , wenn dies nicht der Fall ist. Graeme Perrows Antwort ist gut, wenn Sie diese Datei nicht erstellen wollen, aber sie ist anfällig für eine Race Condition: Wenn ein anderer process die Datei dazwischen erstellt, prüfen Sie, ob sie existiert und Sie öffnen sie tatsächlich, um darauf zu schreiben . (Lachen Sie nicht … dies könnte negative Auswirkungen auf die Sicherheit haben, wenn die erstellte Datei ein Symlink ist!)

Wenn Sie die Existenz prüfen und die Datei erstellen möchten, falls sie nicht vorhanden ist, atomar, damit es keine Wettlaufbedingungen gibt, verwenden Sie Folgendes :

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

Ja. Verwenden Sie stat (). Siehe Link .

Stat wird fehlschlagen, wenn die Datei nicht existiert, sonst höchstwahrscheinlich erfolgreich. Wenn es existiert, aber Sie keinen Lesezugriff auf das Verzeichnis haben, in dem es existiert, wird es auch fehlschlagen, aber in diesem Fall wird jede Methode fehlschlagen (wie können Sie den Inhalt eines Verzeichnisses überprüfen, das Sie nicht entsprechend den Zugriffsrechten sehen können? Einfach, du kannst nicht).

Oh, wie jemand anderes erwähnt, können Sie auch access () verwenden. Allerdings bevorzuge ich stat (), als ob die Datei existiert, wird es mir sofort viele nützliche Informationen (wann wurde es zuletzt aktualisiert, wie groß ist es, Eigentümer und / oder Gruppe, die die Datei besitzt, Zugriffsberechtigungen usw.) .

Von der Visual C ++ – Hilfe würde ich dazu neigen, mitzugehen

 /* 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" ); } } 

Beachtenswert sind auch die Mode-Werte von _access (const char * path, int mode )

00 Nur Existenz

02 Schreibberechtigung

04 Leseerlaubnis

06 Lese- und Schreibberechtigung

Da Ihr Fopen in Situationen fehlschlagen konnte, in denen die Datei vorhanden war, aber nicht wie gewünscht geöffnet werden konnte.

Edit: Lies gerade Meckis Beitrag. stat () sieht nach einem besseren Weg aus. Hör mal.

 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 } 

Ich denke, dass die access () – function, die in unistd.h wird, eine gute Wahl für Linux (Sie können auch stat verwenden ).

Sie können es wie folgt verwenden:

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

Und Sie erhalten folgende Ausgabe:

 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 

Sie können die function realpath () verwenden.

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