Manera más rápida de verificar si el archivo existe o no

La forma en que estoy usando implica tratar de abrir () el archivo que se va a comprobar,

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

¿Existe una forma más rápida y menos intensiva de recursos? … ¿Una forma específica para Unix / Linux? ¿Una forma de Windows? ¿Y preferiblemente, una forma portátil compatible con Posix (como supuestamente lo es anteriormente)? Se está haciendo muchas veces (1000), así que prefiero no abrir y cerrar archivos innecesariamente sin una buena razón.

————————————————– —————
Editar De acuerdo, según las respuestas a continuación, reuní la siguiente función para comprobar si el archivo (ya 🙂 existe en un posix, windows, otra forma portátil …

 /* ========================================================================== * 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() --- */ 

Los métodos access () y fopen () probados y funcionan bien. No se puede probar PathFileExists () para Windows. Y todavía quiero averiguar qué símbolos # define’ed para verificar de forma automática y sin ambigüedades las comstackciones condicionales.

En Windows, hay PathFileExists () .

En un sistema POSIX, tiene stat () o access () .

Dicho esto, si comprueba la existencia del archivo porque su código necesita el archivo, este es el enfoque incorrecto: los sistemas de archivos están fuera del control de su progtwig, por lo que esta sería una condición de carrera, la única forma correcta sería Manejar errores al abrir el archivo.

Estás pensando en el problema de la manera incorrecta. Nunca debe “verificar si un archivo ya existe”, ya que tiene una carrera TOCTOU inherente, entre el momento en que se verifica si el archivo existe y el momento en que actúa sobre esa información, puede aparecer otro proceso y cambiar si el archivo existe, haciendo que el cheque no sea válido.

Lo que haces depende de por qué quieres saber. Un caso muy común es que solo desea crear el archivo si aún no existe, en cuyo caso utiliza la función de open nivel inferior en el modo O_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 */ } 

Otro caso muy común es que desea crear el archivo si no existe, o agregar datos nuevos al archivo si es que existe; esto se puede hacer con el modo "a" para O_APPEND o O_APPEND indicador O_APPEND para open .