检查C文件是否存在的最好方法是什么? (跨平台)

有没有比简单地打开文件更好的方法?

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

查找在unistd.h找到的access()函数。 你可以用你的功能替换

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

您也可以使用R_OKW_OKX_OK来代替F_OK来检查读取权限,写入权限和执行权限(分别)而不是存在,并且可以将它们中的任何一个(或者同时检查读取写入权限使用R_OK|W_OK

更新 :请注意,在Windows上,不能使用W_OK来可靠地测试写权限,因为访问函数不考虑DACL。 access( fname, W_OK )可能会返回0(成功),因为文件没有设置只读属性,但您仍然可能没有权限写入该文件。

像这样使用stat:

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

并像这样调用它:

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

通常当你想检查一个文件是否存在,这是因为你想创建该文件,如果没有。 如果你不想创建这个文件,Graeme Perrow的答案是好的,但是如果你这样做的话,它很容易受到竞争条件的影响:另一个进程可以在你检查它是否存在之间创建文件,并且实际打开它来写入文件。 (不要笑…如果创建的文件是符号链接,这可能会有安全隐患!)

如果你想检查是否存在, 创建文件,如果它不存在, 原子,以便没有竞争条件,然后使用此:

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

是。 使用stat()。 请参阅链接 。

如果文件不存在,Stat将会失败,否则很可能会成功。 如果它确实存在,但你没有对它所在的目录的读访问权限,它也将失败,但是在这种情况下,任何方法都会失败(你怎么检查根据访问权限可能看不到的目录的内容?简单地说,你不能)。

哦,正如别人提到的,你也可以使用access()。 然而,我更喜欢stat(),就好像文件存在一样,它会立即得到很多有用的信息(何时上次更新,它有多大,拥有文件的拥有者和/或组,访问权限等等) 。

从Visual C ++的帮助,我倾向于去

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

另外值得注意的_accesss模式值(const char * path, int mode

00只存在

02写权限

04读取权限

06读写权限

因为你的fopen可能在文件存在的情况下失败,但不能按照要求打开。

编辑:只要读Mecki的帖子。 stat()看起来像一个更好的方式去。 何哼。

 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 } 

我认为在unistd.h找到的access()函数对于Linux是个不错的选择(你也可以使用stat )。

你可以像这样使用它:

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

你得到以下输出:

 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 

你可以使用realpath()函数。

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