¿Cuál es la mejor manera de comprobar si existe un archivo en C?

Resuelto Dave Marshall asked hace 15 años • 8 respuestas

¿Existe una manera mejor que simplemente intentar abrir el archivo?

int exists(const char *fname)
{
    FILE *file;
    if ((file = fopen(fname, "r")))
    {
        fclose(file);
        return 1;
    }
    return 0;
}
Dave Marshall avatar Oct 23 '08 21:10 Dave Marshall
Aceptado

Busque la access()función, que se encuentra en unistd.h. Puedes reemplazar tu función con

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

En Windows (VC) unistd.hno existe. Para que funcione es necesario definir:

#ifdef WIN32
#include <io.h>
#define F_OK 0
#define access _access
#endif

También puede usar R_OK, W_OKy X_OKen lugar de F_OKpara verificar el permiso de lectura, el permiso de escritura y el permiso de ejecución (respectivamente) en lugar de la existencia, y puede O cualquiera de ellos juntos (es decir, verificar el permiso de lectura y escritura usando R_OK|W_OK)

Actualización : tenga en cuenta que en Windows, no puede utilizar W_OKpara probar de manera confiable el permiso de escritura, ya que la función de acceso no tiene en cuenta las DACL. access( fname, W_OK )puede devolver 0 (éxito) porque el archivo no tiene establecido el atributo de solo lectura, pero aún así es posible que no tenga permiso para escribir en el archivo.

Graeme Perrow avatar Oct 23 '2008 14:10 Graeme Perrow

Úselo statasí:

#include <sys/stat.h>   // stat
#include <stdbool.h>    // bool type

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

y llámalo así:

#include <stdio.h>      // printf

int main(int ac, char **av) {
    if (ac != 2)
        return 1;

    if (file_exists(av[1]))
        printf("%s exists\n", av[1]);
    else
        printf("%s does not exist\n", av[1]);

    return 0;
}
codebunny avatar Oct 23 '2008 15:10 codebunny

Por lo general, cuando desea verificar si un archivo existe, es porque desea crear ese archivo si no existe. La respuesta de Graeme Perrow es buena si no desea crear ese archivo, pero es vulnerable a una condición de carrera si lo hace: otro proceso podría crear el archivo mientras usted verifica si existe y lo abre para escribir en él. . (No se ría... ¡esto podría tener graves implicaciones de seguridad si el archivo creado fuera un enlace simbólico!)

Si desea verificar la existencia y crear el archivo si no existe, de forma atómica para que no haya condiciones de carrera, use esto:

#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 */
}
Dan Lenski avatar Oct 23 '2008 17:10 Dan Lenski