Re: parcours récursif de répertoire

トップ ページ

このメッセージに返信
著者: Edgar Bonet
日付:  
To: Guilde
題目: Re: parcours récursif de répertoire
Le mercredi 5 mars, Benoit Lion a écrit :
> Je voudrais faire un programme qui parcours tous les fichiers d'un
> répertoire et de ses sous-répertoires. J'ai fait cela dans mes
> lointaines études, mais j'ai oublié. Quelqu'un aurait-il un exemple
> récursif en langage c ?


Un exemple en pseudo code (pseudo C...) :

int crawl(char *directory)
{
    int ret;
    char *entry;


    /* Go to the directory. */
    ret = chdir(directory);
    if (ret == -1) {
        perror(directory);
        return -1;
    }


    /* Scan all the entries. */
    foreach (entry in the directory) {
        if (is_directory(entry)) {
            ret = crawl(entry);         /* recursive call */
            if (ret == -1) return -1;   /* stop everything if error */
        }
        else do_stuff_with_file(entry);
    }


    /* Get back. */
    chdir("..");
    return 0;
}


Pour transformer ça en vrai code :

    foreach (entry in the directory)    -> man 3 readdir
    is_directory(entry)                 -> man 2 stat


do_stuff_with_file() représente bien-sûr l'action que tu veux faire sur
chaque fichier.

Variations :

    - tu supprimes la ligne « stop everything if error » si tu ne veux
      pas arrêter la récursion à la première erreur.


    - tu remplaces la boucle foreach par deux boucles :


        foreach (entry in the directory)
            if (is_directory(entry)) crawl(entry);
        foreach (entry in the directory)
            if (!is_directory(entry)) do_stuff_with_file(entry);


      si tu veux traiter le contenu des sous-répertoires avant celui de
      leurs parents. Tu inverses l'ordre des boucles ci-dessus dans le
      cas contraire. Cependant, cela demande de parcourir le répertoire
      avec readdir() deux fois (man rewinddir), à moins de garder en
      mémoire son contenu.


    - tu ne fais pas de chdir, mais alors tu dois construire les chemins
      relatifs au répertoire de départ :


        foreach (entry in the directory) {
            char *path = malloc(strlen(directory) + strlen(entry) + 2);
            if (!path) {
                perror("malloc");
                exit(EXIT_FAILURE);     /* ENOMEM: we are doomed */
            }
            strcat(strcat(strcpy(path, directory), "/"), entry);
            if (is_directory(path)) crawl(path);
            else do_stuff_with_file(path);
            free(path);
        }


-- 
Edgar Bonet                         Tél    : 04 76 88 10 96
Laboratoire Louis Néel -- CNRS      Mobile : 06 77 19 79 39
25 av. des Martyrs, BP 166          Fax    : 04 76 88 11 91
38042 Grenoble cedex 9, France      e-mail : guilde@???