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

Joh*_*osh 2 c

我正在使用的方式只是尝试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 */
Run Code Online (Sandbox Code Playgroud)

是否有更快,更少资源的方式?... 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 <unistd.h>
  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() --- */
Run Code Online (Sandbox Code Playgroud)

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

zwo*_*wol 5

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

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

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 */
}
Run Code Online (Sandbox Code Playgroud)

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