Utilice la función opendir en C

Jinku Hu 12 octubre 2023
  1. Utilice la función opendir para abrir una secuencia de directorio
  2. Utilice la función readdir para iterar sobre las entradas del directorio
Utilice la función opendir en C

Este artículo explicará varios métodos de cómo utilizar la función opendir en C.

Utilice la función opendir para abrir una secuencia de directorio

La función opendir es parte de la especificación POSIX y se define en el archivo de encabezado <dirent.h>. La función toma un único argumento de puntero char para especificar el nombre del directorio a abrir. opendir devuelve la estructura DIR* o NULL si se encuentra un error. El tipo de datos DIR se implementa para representar un flujo de directorio, pero el usuario no debe asignar objetos del tipo DIR. En el siguiente código de ejemplo, tomamos el nombre del directorio del primer argumento de la línea de comandos y pasamos el valor a la función opendir.

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  DIR *dp;
  struct dirent *dirp;

  if (argc != 2) {
    fprintf(stderr, "Usage: ./program directory_name\n");
    exit(EXIT_FAILURE);
  }

  dp = opendir(argv[1]);

  while ((dirp = readdir(dp)) != NULL) printf("%s\n", dirp->d_name);

  closedir(dp);
  exit(EXIT_SUCCESS);
}

Utilice la función readdir para iterar sobre las entradas del directorio

Una vez que el flujo de directorio está abierto y recuperamos el DIR* válido, podemos leer cada entrada en él usando la función readdir. Cada llamada a la función readdir devuelve un puntero a la estructura dirent que representa la siguiente entrada del directorio. Cuando se alcanza el final de la secuencia del directorio, readdir devuelve NULL. Por lo tanto, implementamos un bucle simple while que imprime cada entrada en el flujo de directorio abierto. Modificamos el código alrededor de las llamadas de función opendir y closedir para comprobar si hay errores y generar el mensaje correspondiente para su depuración. Siempre es una práctica buena y segura comprobar si las funciones de la biblioteca se han devuelto correctamente.

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  DIR *dp;
  struct dirent *dirp;

  if (argc != 2) {
    fprintf(stderr, "Usage: ./program directory_name\n");
    exit(EXIT_FAILURE);
  }

  errno = 0;
  if ((dp = opendir(argv[1])) == NULL) {
    switch (errno) {
      case EACCES:
        printf("Permission denied\n");
        break;
      case ENOENT:
        printf("Directory does not exist\n");
        break;
      case ENOTDIR:
        printf("'%s' is not a directory\n", argv[1]);
        break;
    }
    exit(EXIT_FAILURE);
  }

  while ((dirp = readdir(dp)) != NULL) printf("%s\n", dirp->d_name);

  if (closedir(dp) == -1) perror("closedir");

  exit(EXIT_SUCCESS);
}

Alternativamente, podemos agregar algunas declaraciones condicionales de verificación de errores para la función readdir porque el ejemplo anterior puede producir una salida poco clara cuando el nombre del directorio no es válido o se produjo un error diferente. El siguiente código generará adicionalmente el estado de fin de directorio alcanzado después de la iteración exitosa.

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  DIR *dp;
  struct dirent *dirp;

  if (argc != 2) {
    fprintf(stderr, "Usage: ./program directory_name\n");
    exit(EXIT_FAILURE);
  }

  errno = 0;
  if ((dp = opendir(argv[1])) == NULL) {
    switch (errno) {
      case EACCES:
        printf("Permission denied\n");
        break;
      case ENOENT:
        printf("Directory does not exist\n");
        break;
      case ENOTDIR:
        printf("'%s' is not a directory\n", argv[1]);
        break;
    }
    exit(EXIT_FAILURE);
  }

  errno = 0;
  while ((dirp = readdir(dp)) != NULL) printf("%s\n", dirp->d_name);

  if (errno != 0) {
    if (errno == EBADF)
      printf("Invalid directory stream descriptor\n");
    else
      perror("readdir");
  } else {
    printf("End-of-directory reached\n");
  }

  if (closedir(dp) == -1) perror("closedir");

  exit(EXIT_SUCCESS);
}
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artículo relacionado - C File