[Sistema operativo Linux] La programación del sistema Linux realiza un recorrido recursivo de directorios y explica en detalle el uso de opendir, readdir, closedir, snprintf, strcmp y otras funciones

En la programación del sistema Linux, a menudo es necesario recorrer el directorio para obtener todos los archivos y subdirectorios del directorio. Atravesar directorios de forma recursiva es un método común que se puede implementar utilizando el lenguaje C. Este blog presentará en detalle cómo usar el lenguaje C para implementar el proceso de recorrer directorios de forma recursiva, brindar ejemplos de código correspondientes y explicar el uso de funciones relacionadas.
inserte la descripción de la imagen aquí

1. Introducción de funciones relacionadas

1.1 abrirdir()

1.1.1 Prototipo de función, parámetros y valor de retorno

opendirLa función se usa para abrir un directorio y devolver un DIRpuntero al tipo, que se usa para operaciones de directorio posteriores.


prototipo:

DIR *opendir(const char *path);

parámetro:

  • path: Ruta al directorio a abrir.

valor de retorno:

  • Valor de retorno: si el directorio se abre con éxito, se devuelve un DIRpuntero al tipo ; si falla, se devuelve NULL.

1.1.2 Ejemplo de función

Aquí hay un ejemplo del uso opendirde una función para abrir un directorio:

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

int main() {
    
    
    const char *path = "/path/to/directory";
    DIR *dir = opendir(path);
    
    if (dir == NULL) {
    
    
        perror("opendir");
        return -1;
    }
    
    // 目录操作...
    
    closedir(dir);
    
    return 0;
}

1.1.3 Código Explicación

En el ejemplo anterior, primero definimos la ruta del directorio para abrir path, luego usamos opendirla función para abrir el directorio y almacenamos el puntero devuelto en diruna variable. Luego, podemos realizar algunas operaciones de directorio, como usar readdirfunciones para leer archivos en el directorio. Finalmente, usamos closedirla función para cerrar el directorio.

Si opendirla función falla, regresa NULLy almacena el mensaje de error en una variable global errno. Podemos usar perrorla función para imprimir mensajes de error para depurar y solucionar problemas

Cabe señalar que después de usar DIRel puntero del tipo, debe recordar usar closedirla función para cerrar el directorio para liberar recursos relacionados.



1.2 readdir()

1.2.1 Prototipo de función, parámetro, valor de retorno y definición de estructura

readdirLa función se usa para leer los archivos en el directorio y devuelve un direntpuntero a la estructura.


prototipo:

struct dirent *readdir(DIR *dir);

parámetro:

  • dir: Un puntero al directorio abierto.

valor de retorno:

  • Valor devuelto: si el siguiente archivo se lee con éxito, direntse devuelve un puntero a la estructura; si se llega al final del directorio o se produce un error, se devuelve NULL.

direntLa estructura se define de la siguiente manera:

struct dirent {
    
    
    ino_t d_ino;               // 文件的inode号
    off_t d_off;               // 文件在目录中的偏移量
    unsigned short d_reclen;   // 文件名的长度
    unsigned char d_type;      // 文件的类型
    char d_name[256];          // 文件名
};

1.2.2 Ejemplos de funciones

Aquí hay un readdirejemplo del uso de una función para leer un archivo en un directorio:

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

int main() {
    
    
    const char *path = "/path/to/directory";
    DIR *dir = opendir(path);
    
    if (dir == NULL) {
    
    
        perror("opendir");
        return -1;
    }
    
    struct dirent *entry;
    
    while ((entry = readdir(dir)) != NULL) {
    
    
        printf("%s\n", entry->d_name);
    }
    
    closedir(dir);
    
    return 0;
}

1.2.3 Código Explicación

En el ejemplo anterior, primero usamos opendirla función para abrir el directorio y almacenar el puntero devuelto en diruna variable. Luego, usamos un bucle para leer cada archivo en el directorio. readdirLa función devolverá un direntpuntero a la estructura, podemos d_nameobtener el nombre del archivo accediendo a los miembros y realizar las operaciones correspondientes. En el ejemplo, simplemente usamos printfla función para imprimir el nombre del archivo. Finalmente, usamos closedirla función para cerrar el directorio.

Cabe señalar que cuando readdirla función devuelve NULL, significa que se ha leído el final del directorio o se ha producido un error. Por lo tanto, podemos NULLdeterminar si continuar leyendo los archivos en el directorio juzgando si el valor devuelto es .



1.3 cerradoir()

1.3.1 Prototipo de función, parámetros y valor de retorno

closedirLa función se usa para cerrar el directorio abierto por la función antes opendiry liberar recursos relacionados.


prototipo:

int closedir(DIR *dir);

parámetro:

  • dir: Un puntero al directorio abierto.

valor de retorno:

  • Valor devuelto: 0 si el directorio se cerró correctamente o -1 si se produjo un error.

1.3.2 Ejemplo de función

Aquí hay un ejemplo del uso de una closedirfunción para cerrar un directorio:

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

int main() {
    
    
    const char *path = "/path/to/directory";
    DIR *dir = opendir(path);
    
    if (dir == NULL) {
    
    
        perror("opendir");
        return -1;
    }
    
    // 目录操作...
    
    if (closedir(dir) == -1) {
    
    
        perror("closedir");
        return -1;
    }
    
    return 0;
}

1.3.3 Código Explicación

En el ejemplo anterior, primero usamos opendirla función para abrir el directorio y almacenar el puntero devuelto en diruna variable. A continuación, podemos hacer algo de manipulación de directorios. Finalmente, usamos closedirla función para cerrar el directorio y verificar si el valor de retorno es -1 para ver si ocurrió un error.

Cabe señalar que closedirla función liberará recursos relacionados con el directorio, por lo que después de usar el directorio, debe recordar llamar a la closedirfunción para cerrar el directorio.



1.4 snprintf()

1.4.1 Prototipo de función, parámetros y valor de retorno

snprintfLa función es una función de formato de cadena segura para generar datos formateados en una cadena.


prototipo:

int snprintf(char *str, size_t size, const char *format, ...);

parámetro:

  • str: Puntero a la cadena utilizada para almacenar el resultado formateado.
  • size: El tamaño de la cadena que almacena el resultado formateado.
  • format: cadena de formato, especifique el formato de salida.

valor de retorno:

  • Valor devuelto: Devuelve el número de caracteres escritos en la cadena (sin incluir el terminador) en caso de éxito o un valor negativo en caso de error.

snprintffunciona printfcomo una función, pero almacena el resultado formateado en la cadena especificada en lugar de enviarlo a la salida estándar.


1.4.2 Ejemplo de función

Aquí hay un snprintfejemplo usando la función:

#include <stdio.h>

int main() {
    
    
    char buffer[100];
    int num = 42;
    const char *str = "Hello, world!";
    
    int len = snprintf(buffer, sizeof(buffer), "Number: %d, String: %s", num, str);
    
    if (len >= sizeof(buffer)) {
    
    
        printf("Buffer is too small\n");
        return -1;
    }
    
    printf("Formatted string: %s\n", buffer);
    
    return 0;
}

1.4.3 Código Explicación

En el ejemplo anterior, primero definimos una matriz de caracteres de tamaño 100 bufferpara almacenar el resultado formateado. Luego, definimos una variable entera numy una variable de cadena strpara pasar a la cadena de formato. A continuación, usamos snprintfla función para almacenar el resultado formateado buffery enviarlo a la salida estándar. Finalmente, verificamos lensi el valor devuelto excede bufferel tamaño de para ver si el búfer es lo suficientemente grande para contener el resultado formateado.

Cabe señalar que snprintfla función se formateará de acuerdo con la cadena de formato y los parámetros especificados, y almacenará el resultado en la cadena especificada. Garantiza que el resultado formateado no exceda el tamaño especificado y trunca automáticamente la cadena si es necesario. Por lo tanto, el uso snprintfde funciones puede evitar el problema del desbordamiento del búfer.



1.5 strcmp()

1.5.1 Prototipo de función, parámetros y valor de retorno

strcmpFunción para comparar dos cadenas para la igualdad.


prototipo:

int strcmp(const char *s1, const char *s2);

parámetro:

  • s1: La primera cadena a comparar.
  • s2: La segunda cadena a comparar.

valor de retorno:

  • Valor devuelto: Devuelve 0 si las dos cadenas son iguales; devuelve un número negativo si la primera cadena es menor que la segunda; devuelve un número positivo si la primera cadena es mayor que la segunda.

strcmpLa función compara las dos cadenas carácter por carácter, lexicográficamente, hasta que se encuentra un carácter desigual o se encuentra el final de la cadena \0. Devuelve 0 si las dos cadenas son iguales; devuelve un número negativo si la primera cadena es lexicográficamente anterior a la segunda; devuelve un número negativo si la primera cadena es lexicográficamente segunda Después de la cadena, se devuelve un número positivo.


1.5.2 Ejemplos de funciones

Aquí hay un strcmpejemplo que usa una función para comparar dos cadenas:

#include <stdio.h>
#include <string.h>

int main() {
    
    
    const char *s1 = "Hello";
    const char *s2 = "World";
    
    int result = strcmp(s1, s2);
    
    if (result == 0) {
    
    
        printf("The strings are equal\n");
    } else if (result < 0) {
    
    
        printf("The first string is less than the second string\n");
    } else {
    
    
        printf("The first string is greater than the second string\n");
    }
    
    return 0;
}

1.5.3 Código Explicación

En el ejemplo anterior, definimos dos cadenas s1y s2luego usamos strcmpla función para compararlas. Dependiendo del valor de retorno, mostramos el resultado correspondiente.

Cabe señalar que strcmpla función compara el contenido de las cadenas, no las direcciones de las cadenas. Por lo tanto, incluso si las direcciones de las dos cadenas son diferentes, siempre que su contenido sea el mismo, strcmpla función devolverá 0. Además, strcmplas funciones distinguen entre mayúsculas y minúsculas, y si desea comparaciones que no distingan entre mayúsculas y minúsculas, puede usar strcasecmpfunciones.



2. Implementación de directorio transversal recursivo

2.1 Código de ejemplo:

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>

void traverse_directory(const char *path) {
    
    
    DIR *dir;
    struct dirent *entry;
    struct stat file_stat;
    
    // 打开目录
    dir = opendir(path);
    if (dir == NULL) {
    
    
        perror("opendir");
        return;
    }
    
    // 读取目录中的每个文件
    while ((entry = readdir(dir)) != NULL) {
    
    
        // 构建文件的完整路径
        char file_path[1024];
        snprintf(file_path, sizeof(file_path), "%s/%s", path, entry->d_name);
        
        // 获取文件的信息
        if (lstat(file_path, &file_stat) < 0) {
    
    
            perror("lstat");
            continue;
        }
        
        // 判断文件类型
        if (S_ISDIR(file_stat.st_mode)) {
    
    
            // 如果是目录,则递归遍历
            if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
    
    
                continue;
            }
            traverse_directory(file_path);
        } else {
    
    
            // 如果是文件,则打印文件名
            printf("%s\n", file_path);
        }
    }
    
    // 关闭目录
    closedir(dir);
}

int main(int argc,char *argv[]) {
    
    
    
    traverse_directory(argv[]);
    
    return 0;
}

2.2 Explicación del código

En el código anterior, definimos una traverse_directoryfunción para recorrer directorios recursivamente. Esta función toma una ruta como argumento, primero abre el directorio y luego lee cada archivo en el directorio. Para cada archivo, primero construimos la ruta completa al archivo, luego usamos lstatuna función para obtener la información del archivo. Si el archivo es un directorio, la función se llama recursivamente traverse_directory; si el archivo es un archivo normal, se imprime el nombre del archivo. Finalmente, cerramos el directorio.

En mainla función, especificamos la ruta del directorio a recorrer y llamamos traverse_directorya la función a recorrer.

dirent.hCabe señalar que en el código anterior, los archivos de encabezado se usan sys/stat.hpara operar directorios y archivos, y los archivos stdio.hde encabezado string.hse usan para realizar operaciones de cadena. Además, las funciones se usan en el código lstatpara obtener información sobre archivos en lugar de statfunciones porque lstatlas funciones pueden manejar enlaces simbólicos.

Supongo que te gusta

Origin blog.csdn.net/Goforyouqp/article/details/132232262
Recomendado
Clasificación