IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Parcours d'un dossier


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2014
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2014
    Messages : 80
    Par défaut Parcours d'un dossier
    Bonjour à tous,

    j'ai un petit souci de compréhension concernant le parcoure d'un dossier

    donc j'ai un dossier Test qui contient 2 dossier que j'ai appelé dossier1 et dossier2 ainsi qu'un fichier que j'ai appelé fichier1 ce que j'aimerai faire maintenant c'est affiché le nom des fichiers et dossiers que contient le dossier Test donc à savoir : dossier1,dossier2 et fichier1.
    Merci de m'aider s'il vous plait.

    voici mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
     
    int main()
    {
        DIR* rep = NULL;
        struct dirent* fichierLu = NULL; 
        rep = opendir("/home/Test");
     
        if (rep == NULL)  {
            exit(1);
       }
     
        while ((fichierLu = readdir(rep)) != NULL) {
              printf("Le fichier lu s'appelle '%s'\n", fichierLu->d_name);
        }
     
        if (closedir(rep) == -1) {
            exit(-1);
        }
     
        return 0;
    }
    là ça part en vrille ça m'affiche pas ce que je veux, j'aimerai également savoir s'il vous plait est-ce que readdir() lit uniquement les fichiers ou aussi les dossiers donc est-ce que la structure Dirent représente uniquement un fichier ou un fichier et un dossier.

  2. #2
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Bonsoir,

    Il se fait tard alors je m’efforcerais dans la limite du possible vous apportez quelques éléments de compréhension. Tout d’abord il faut comprendre qu’un fichier possède un non et d’autres informations comme les autorisations de lecture/écriture, la date de dernière modification, etc. Toutes ces informations sont stockées dans un inode (dit nœud d'index qui est une structure de données contenant des informations à propos d'un fichier stocké dans certains systèmes de fichiers ext4, ext2, etc...). Qui contient également la taille du fichier et son emplacement sur votre disque dur.

    Le répertoire quant à lui est également un fichier qui a la particularité de contenir que des i-noeud et les non d’autres fichiers. Chaque entré du répertoire représente un lien avec inode d’un fichier.

    la fonction readdir revoir un pointeur sur une structure détaillant la prochaine entrée du répertoire et NULL si c’est la fin du répertoire.
    Voici un exemple ci-dessous a vous de l’adapter et compléter :Attention le code source ci-dessous est susceptible de comporter des erreurs
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
     
    /*
     ============================================================================
     Name        : source.c
     Date        : 20/01/2017
     Author      : SAMBIA39
     Version     : 0.1
     Copyright   : Copyright © 2017 SAMBIA39 All rights reserved.
     Description : Ansi-style
     ============================================================================
     */
     
    #define REP_DEFAULT "/"
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <dirent.h>
    #include <string.h>
    #include <sys/stat.h>
     
     
     
    void f_scan_print_rep( char *ptr_name,
                          int id ){
     
        DIR *pDir;
        struct dirent *pEntryInode;
        struct stat info;
        extern int errno;
     
        errno = 0;
        if( NULL == ( pDir = opendir(ptr_name)) ){
            fprintf( stderr, "(%d)\t:%s:%s\n\t:%s\n", errno,
                    "impossible d'ouvrir le repertoire:", ptr_name,
                    strerror(errno) );
            return;
        }
     
        chdir( ptr_name );
        while( NULL != (pEntryInode = readdir(pDir) ) ){
            lstat(pEntryInode->d_name, &info );
     
            /*
             *  Répertoire trouvé mais "." & ".."
             *  sont ignioré.
             */
            if( S_ISDIR(info.st_mode) ){
                if( (0 == strcmp(".", pEntryInode->d_name)) ||
                   (0 == strcmp("..", pEntryInode->d_name)) )
                    continue;
                fprintf( stdout, "%*s%s/\n", id,"", pEntryInode->d_name );
     
                /*
                 *  Appel récursive à une nouvelle entrer
                 */
                f_scan_print_rep(pEntryInode->d_name, id+4 );
            }else
                fprintf( stdout, "%*s%s/\n", id,"", pEntryInode->d_name );
        }
        chdir("..");
        closedir(pDir);
     
    }
     
    int main( int argc, char **argv ){
     
        f_scan_print_rep( REP_DEFAULT, 0 );
        return EXIT_SUCCESS;
    }

    Cependant il faut faire attention le pointeur retourner par la fonction readdir est une variable statique qui peut-être écrasée à chaque appel elle n'est donc pas ré-entrante et à ne pas utiliser avec des threads il faut utiliser readdir_s qui prend deux arguments supplémentaires pour stocker la valeur de retour et mémoriser la position suivante dans le répertoire. exemple d’utilisation
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
        DIR *pDir = NULL;
        struct dirent entryInode;  //Résultat       
        struct dirent *ptr_mem;     //Mémorisation
     
        for( ;; ){
            if( 0 != readdir_r(pDir, &entryInode, &ptr_mem) )
                return EXIT_FAILURE;
            if( NULL == ptr_mem )
                break;
        }

    à bientôt

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2014
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2014
    Messages : 80
    Par défaut
    un grand merci ça fonctionne nickel,
    j'ai encore une petite question qu'est-ce qui differenci la struct dirent à la struct stat, je veux dire par là que les 2 struct représente un fichier ou un répertoire et que les 2 struct ont un attribut name représentant le nom du fichier ou répertoire,
    Merci.

  4. #4
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Bonjour,

    Citation Envoyé par wear12 Voir le message
    un grand merci ça fonctionne nickel,
    j'ai encore une petite question qu'est-ce qui differenci la struct dirent à la struct stat, je veux dire par là que les 2 struct représente un fichier ou un répertoire et que les 2 struct ont un attribut name représentant le nom du fichier ou répertoire,
    Merci.
    Pour faire simple la structure "stat" est utilisé à l’aide des fonctions "lstat", "stat" et "fstat" afin d’obtenir des informations concernant un fichier. Plus précisément, le noeud d’index des informations sur l’état du fichier.

    Les deux fonctions fournissent un résultat quasi identique à la simple différence que. Lorsque le fichier est un lien symbolique la fonction "lstat" renvoie l'attribue de celui-ci (lien symbolique) tant dit que "stat" retourne les attribues du fichier pointé par le lien.

    La fonction "fstat" est identique à "stat" sauf qu’il prend un descripteur de fichier ouvert

    Tout de même il faut être vigilant, car les attributs de la structure "stat" sont susceptibles d’être différents selon les systèmes.

    La structure "dirent" est une structure qui est utilisée pour avoir des informations sur une entrée donnée. Utiliser dans mon exemple avec la fonction "readdir" elle permet de connaître le prochain flux (entrée) répertoire DIR* et si vous renouvelez l’appel de la fonction "readdir" vous obtiendrez une nouvelle entrée (parcours, répertoire en répertoire).

    Cependant, il faut faire attention, car la fonction "readdir" ne garantit pas la numération des fichiers et sous-répertoire d’un répertoire; dans le cas où un processus actif manipule (modifier, supprime, etc.) un fichiers au même moment.

    Citation Envoyé par wear12 Voir le message
    ......
    je veux dire par là que les 2 struct représente un fichier ou un répertoire et que les 2 struct ont un attribut name représentant le nom du fichier ou répertoire,
    Merci.
    Pour faire très simple "dirent" est utilisé pour avoirs les informations sur les répertoires et fichiers du sous-répertoire et "stat" sur les fichiers.
    "stat" ne possèdent pas d’attribue name. "dirent" oui "d_name[256]" définis pour le non du fichier.

    à bientôt

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2014
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2014
    Messages : 80
    Par défaut
    un grand merci, est-ce normale que la macro S_ISDIR(), renvoi true même lorsque je lui envoie une entrée représentant un fichier, mon but ici étant de lister uniquement les répertoires que contient le dossier test, existe-il une autre fonction standard permettant de savoir si une entrée est un dossier ou un fichier ou dois-je la coder moi même ?
    Merci encore.

    ce code m'affiche tout a savoir les répertoires mais également les fichier du dossier test.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
     
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <dirent.h>
    #include <string.h>
    #include <sys/stat.h>
     
     
     
    int main( int argc, char **argv ){
     
       DIR *pDir;
       struct dirent *pEntryInode;
       struct stat info;
     
     
       pDir = opendir("/test/");
     
        while( NULL != (pEntryInode = readdir(pDir) ) ){
     
            lstat(pEntryInode->d_name, &info );
     
            if( S_ISDIR(info.st_mode) ){
     
                fprintf( stdout, "%*s%s/\n", id,"", pEntryInode->d_name );
            }
    }
     
        closedir(pDir);
     
    }

  6. #6
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Bonjour,

    Avant de répondre, je vais apporter quelques éléments de compréhension:
    il faut savoir qu’il existe trois types de fichiers sous UNIX, GNU/Linux: Les répertoires, Les fichiers ordinaires et Les fichiers spéciaux (donc tout est fichier sous UNIX et GNU/Linux)

    Les fichiers ordinaires sont des fichiers qui sont stockés sur le disque qui non pas de nom, mais repéré ou reconnue par un numéro d’index qui est un indice dans la table des noeuds d’index. Cette table d’index est placée au début de chaque région du disque qui contient un système de fichiers et des informations sur le fichier. Cette table ne contient ni nom de fichier et donnée; Que des informations comme le type de fichier (répertoire, spéciale ou ordinaire, le propriétaire du fichier sont groupes, sa taille, etc.). Il faut comprendre également que les fichiers ordinaires contiennent que des octets organiser en tableau linéaire, dont chaque suite d’octets peut être lu ou écrit. La lecture ou l’écriture de ces octets commence par un octet dont l’emplacement est spécifié par un pointeur de fichier qui peut prendre n’importe quelles valeurs et ce même au-delà du fin de fichier.

    Les répertoires quant à eux sont stockés ou sauvegardés comme des fichiers ordinaires marqués comme étant un répertoire. Plus en détail chaque répertoire est formé d’une table à deux colonnes dont la première est une colonne qui contient que des noms et la deuxième que des numéros d’index correspondant aux noms des fichiers et les deux éléments formes ce que l’on appelle un lien. Lorsque le kernel veut accéder à un fichier par son nom, il va alors rechercher systématiquement le numéro d’index dans un répertoire et ce numéro à son tour lui fournit des informations comme par exemple où se trouvent les données si vous souhaité les consultés.

    Les fichiers spéciaux: sont des fichiers dits spéciaux parce qu'ils peuvent être soit un périphérique (fichier blocs qui contiennent des tableaux de bloc de taille fixe. Et des fichiers de type caractère dépourvu de structure interne fixe) où un fichier FIFO (first in last out qui est un mécanisme utiliser pour transférer des données entre processus). Un fichier spécial possède un noeud d’index, mais ce noeud ne pointe sur aucune donnée sur le disque. À la place elle contient un numéro de périphérique qui est un index dans une table utilisé par le kernel pour identifier ou localiser un programme ou sous programme appeler gestionnaire de périphérique plus précisément "driver" ou "device driver" et lorsqu’une fonction système doit effectuer une opération sur un fichier spécial, elle appelle le sous-programme du driver approprié du périphérique en questions.

    Citation Envoyé par wear12 Voir le message
    ..... est-ce normale que la macro S_ISDIR(), renvoi true même lorsque je lui envoie une entrée représentant un fichier, mon but ici étant de lister uniquement les répertoires que contient le dossier test, existe-il une autre fonction standard permettant de savoir si une entrée est un dossier ou un fichier ou dois-je la coder moi même ?
    Merci encore.
    La réponse à votre question est simple oui c’est normal. Alors pourquoi ? : Comme j'ai mentionné précédemment, lorsque vous voulez accéder à un fichier par son nom, votre kernel va rechercher systématiquement le numéro du fichier dans un répertoire et s’il le trouve, le numéro par la suite lui fournira les informations concernant le fichier . Donc si vous souhaitez identifier, lister ou distinguer les fichiers contenus dans un répertoire des répertoire, vous êtes alors obligé de procéder comme ci-dessous en testant le type de fichier pour savoir si celui-ci est marqué comme étant un répertoire ou fichier. Ce qui donne le code source ci-dessous. Voici certaines informations sur fichiers lien 1; lien 2
    Attention le code source ci-dessous est susceptible de comporter des erreurs
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
     
    /*
     ============================================================================
     Name        : source.c
     Date        : 05/02/2017
     Author      : SAMBIA39
     Version     : 0.1
     Copyright   : Copyright © 2017 SAMBIA39 All rights reserved.
     Description : Ansi-style
     ============================================================================
     */
     
    #define REP_DEFAULT "/Users/DebugUser/Desktop/REP_TEST/"
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <dirent.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <sys/types.h>
     
     
     
    void f_scan_print_rep( char *ptr_name,
                          int id ){
     
        DIR *pDir;
        struct dirent *pEntryInode;
        struct stat info;
        extern int errno;
     
        errno = 0;
        if( NULL == ( pDir = opendir(ptr_name)) ){
            fprintf( stderr, "(%d)\t:%s:%s\n\t:%s\n", errno,
                    "impossible d'ouvrir le repertoire:", ptr_name,
                    strerror(errno) );
            return;
        }
     
        chdir( ptr_name );
        while( NULL != (pEntryInode = readdir(pDir) ) ){
            lstat(pEntryInode->d_name, &info );
     
            /*
             *  Si Répertoire trouvé mais "." & ".."
             *  sont ignioré.
             */
            if( S_ISDIR(info.st_mode) ){
                if( (0 == strcmp(".", pEntryInode->d_name)) ||
                   (0 == strcmp("..", pEntryInode->d_name)) )
                    continue;
                /* En affiche le répertoire */
                fprintf( stdout, "%*s%s/ est un dossier\n", id,"", pEntryInode->d_name );
                /*
                 *  Appel récursive à une nouvelle entrer
                 */
                f_scan_print_rep(pEntryInode->d_name, id+4 );
     
                /* 
                 *  Sinon-si ce n'est pas un répertoire alors on teste 
                 *  si c'est un fichier executable avec les droit utilisateur  
                 *  ou un fichier.
                 */
            }else{
                if( (!S_ISDIR( info.st_mode)) &&
                     ((info.st_mode & S_IRWXU) == S_IRWXU) ){
                    fprintf( stdout, "%*s%s est un fichiers executable\n", id, "",
                            pEntryInode->d_name );
     
                }else if( !S_ISDIR( info.st_mode) )
                    fprintf( stdout, "%*s%s est un fichiers\n", id, "",
                            pEntryInode->d_name );
     
            }
        }
        chdir("..");
        closedir(pDir);
    }
     
     
     
    int main( int argc, char **argv ){
     
        f_scan_print_rep( REP_DEFAULT, 0 );
     
        return EXIT_SUCCESS;
    }

    Code Out : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    Dossier_A/ est un dossier
        Fichier_A1.txt est un fichiers
        Fichier_A2.txt est un fichiers
        Fichier_A3.txt est un fichiers
        Fichier_A4.txt est un fichiers
    Dossier_B/ est un dossier
        Fichier_B1.txt est un fichiers
        Fichier_B2.txt est un fichiers
    Dossier_C/ est un dossier
        Fichier_C1.html est un fichiers
        Fichier_C2.pdf est un fichiers
        Fichier_C3.php est un fichiers
    Dossier_D/ est un dossier
        Fichier_D1.txt est un fichiers
        Fichier_D2.txt est un fichiers
        source_exe est un fichiers executable
    Program ended with exit code: 0

    à bientôt.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Affichage non voulu lors de parcours d'un dossier
    Par obito dans le forum Langage
    Réponses: 5
    Dernier message: 02/03/2009, 16h02
  2. [Tableaux] Script de parcours d'un dossier se stoppant
    Par Couscouss sensei dans le forum Langage
    Réponses: 9
    Dernier message: 27/02/2008, 10h50
  3. Réponses: 6
    Dernier message: 07/07/2007, 19h58
  4. parcours récursif de dossiers selon un niveau un niveau de profondeur
    Par terminatorsk8 dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 21/08/2006, 20h14
  5. problème sur le parcours d'un dossier
    Par cyrill.gremaud dans le forum Langage
    Réponses: 16
    Dernier message: 04/05/2006, 14h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo