检查文件是否存在的最快方法

我正在使用的方式只是尝试fopen()要检查的文件,

/* --- does file exist??? --- */ char fname[999] = "whatever"; /* constructed during execution */ FILE *fp = NULL; /* try to fopen(fname,"r") */ int isfilefound = 0; /* set true if fopen() succeeds */ if ( (fp = fopen(fname,"r")) /* try to fopen() for read */ != NULL ) { /* succeeded */ isfilefound = 1; /* set file found flag */ fclose(fp); } /* and just close the file */ 

是否有更快,更少资源的方式?… unix / linux的特定方式? 一种Windows方式? 并且最好是便携式posix兼容方式(如上所述)? 它已经完成了很多次(1000次),所以我不希望没有任何理由不必要地打开和关闭文件。

————————————————– —————
编辑好了,根据下面的答案,我把以下的小函数放在一起,用于检查文件(已经:)是否存在于posix,windows,其他便携式方式……

 /* ========================================================================== * Function: isfilexists ( path ) * Purpose: check whether file at path exists * -------------------------------------------------------------------------- * Arguments: path (I) pointer to null-terminated char string * containing "path/filename.ext" of * file whose existence is to be determined * (path is relative to pwd unless explicitly * absolute by initial '/' or other syntax) * -------------------------------------------------------------------------- * Returns: ( int ) 1 if file at path exists, or 0 if not * -------------------------------------------------------------------------- * Notes: o conditional compiles for various systems, * depending on whether POSIX or WINDOWS is #define'ed... * o ...method used: * 1: use access() on Posix systems, * 2: PathFileExists() on Windows systems, * 3: fopen() on any other systems. * ======================================================================= */ /* --- entry point --- */ int isfilexists ( char *path ) { /* --- * allocations and declarations * ------------------------------- */ int isexists = 0; /* set true if file at path exists */ FILE *fp = NULL; /* fopen() for non-posix,windows */ #define POSIX /* just for testing */ /* --- * determine whether file at path already exists * ------------------------------------------------ */ #if defined(POSIX) /* posix-compliant system... */ #include  if ( access(path,F_OK) == 0 ) /* file at path exists */ isexists = 1; /* so set file exists flag */ #else #if defined(WINDOWS) /* Windows system... */ isexists = PathFileExists(path); /* set flag if file at path exists */ #else /* --- fopen() for any other non-posix, non-windows system --- */ if ( (fp = fopen(path,"r")) /* try to fopen() for read */ != NULL ) { /* succeeded */ isexists = 1; /* set file exists flag */ fclose(fp); } /* and just close the file */ #endif #endif return ( isexists ); /* back to caller with 1 if file at path exists */ } /* --- end-of-function isfilexists() --- */ 

access()和fopen()方法测试并正常工作。 无法为Windows测试PathFileExists()。 我仍然想弄清楚#define’ed符号是什么,以自动和明确地检查条件编译。

在Windows上,有PathFileExists() 。

在POSIX系统上,您有stat()或access() 。

也就是说,如果你检查文件的存在是因为你的代码需要文件,这是错误的方法 – 文件系统不受你程序的控制,所以这将是一个竞争条件,唯一正确的方法是正确打开文件时处理错误。

你正在以错误的方式思考这个问题。 您不应该“检查文件是否已经存在”,因为它具有固有的TOCTOU竞争 – 在您检查文件是否存在之间以及您对该信息采取行动的时间之间,可能会出现另一个过程并更改是否文件存在,使检查无效。

你做什么取决于你想知道的原因。 一个非常常见的情况是,如果文件尚不存在,您只想创建该文件,在这种情况下,您在O_EXCL模式下使用较低级别的open函数:

 int fd = open("whatever", O_WRONLY|O_CREAT|O_EXCL, 0666); if (fd == -1 && errno == EEXIST) { /* the file already exists */ } else if (fd == -1) { /* report that some other error happened */ } else { FILE *fp = fdopen(fd, "w"); /* write data to fp here */ } 

另一个非常常见的情况是,如果文件不存在,您要创建该文件;如果存在,则将新数据附加到该文件; 这可以通过"a"模式完成fopenO_APPEND标志open