Publi

Algoritmos: Probar la existencia de un fichero con open() en C

Estos días a varios de mis alumnos les ha surgido la necesidad de probar la existencia de un archivo haciendo la llamada al sistema open(). Es bastante sencillo, sólo hay que probar si éste se ha podido abrir (como lectura, por ejemplo, para no tocar el fichero en la medida de lo posible).
Una vez se abre el fichero pueden ocurrir varias cosas:

  • que la llamada a open() no devuelva error. Por tanto el fichero existe
  • que la llamada a open() de error:
    • si el resultado de errno es ENOENT (constante de error), ENOFILE en algunos sistemas o 2 (valor que generalmente vale dicha constante), el fichero no existe
    • si el resultado de errno es distinto, no podemos asegurar que no exista, pero tal vez el nombre de fichero no sea correcto, la ruta no exista, o no tengamos acceso a él.

Para contemplar estos casos creamos la función exists(). Incluyo la función y el código de ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
*************************************************************
* @file exists.c
* @brief Verifica la existencia o no de un fichero
*
* @author Gaspar Fernández <blakeyed@totaki.com>
* http://totaki.com/poesiabinaria/algoritmos/
*************************************************************/


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

short exists(char *fname)
{
  int fd=open(fname, O_RDONLY);
  if (fd<0)         /* error */
    return (errno==ENOENT)?-1:-2;
  /* Si no hemos salido ya, cerramos */
  close(fd);
  return 0;
}

int main(int argc, char *argv[])
{
  int abre=exists("archivo");
  switch (abre)
    {
    case 0: printf ("El archivo existe\n"); break;
    case -1: printf ("El archivo no existe\n"); break;
    case -2: printf ("Ocurrió un error al abrir. %d (%s)\n", errno, strerror(errno)); break;

    default: printf ("Nunca veremos este mensaje");
    }

  return EXIT_SUCCESS;
}

Descargar: exists (1Kb)
Para ejecutarlo podemos probar:

$ ./exists
El archivo no existe
$ touch archivo
$ ./exists
El archivo existe
$ chmod -r archivo # Eliminamos permiso de lectura al fichero
$ ./exists
Ocurrió un error al abrir. 13 (Permission denied)

Puede que también seas de los que piensan que si hay algún error al abrir el archivo, da igual, lo marcamos como no existente, de todas formas no podemos hacer nada con él. Así, construimos una función exists() más intuitiva que devuelve 1 cuando existe y 0 cuando no existe o hay error:

1
2
3
4
5
6
7
8
9
short exists(char *fname)
{
  int fd=open(fname, O_RDONLY);
  if (fd<0)         /* error */
    return 0;
  /* Si no hemos salido ya, cerramos */
  close(fd);
  return 1;
}

También podría interesarte...

There are 3 comments left Ir a comentario

  1. Pingback: Bitacoras.com /

  2. pmike /
    Usando Mozilla Firefox Mozilla Firefox 11.0 en Windows Windows 7

    en este caso tambien se podria poner la funcion principal sin los argnumentos, o sea:

    int main()

    1. Gaspar Fernández / Post Author
      Usando Mozilla Firefox Mozilla Firefox 11.0 en Ubuntu Linux Ubuntu Linux

      Claro que sí ! Lo que pasa es que a mi siempre me gusta ponerlo

Leave a Reply