[C] Parser un arbre représentatif des dossiers

Parser un arbre représentatif des dossiers [C] - C - Programmation

Marsh Posté le 17-11-2010 à 18:56:10    

Bonjour à tous!

 

Je développe actuellement un projet qui est une sorte de 'ls', prenant en paramètre un dossier, ayant pour but de lister les fichiers et sous dossiers en regroupant les fichiers par utilisateur et en calculant le nombre de fichiers et la taille totale de ses fichiers.

 

Je prends un exemple :

 
Code :
  1. quentin@quentin:~$ ./a.out test
  2. test/: quentin (#2, 8000 Bytes) root (#1, 100 Bytes)
  3. test/test2: quentin (#4, 200 Bytes)
 

puis un deuxième pour mettre en évidence la prise en compte des sous-dossiers

Code :
  1. quentin@quentin:~$./a.out -s test
  2. test/: quentin (#6, 8200 Bytes) root (#1, 100 Bytes)
  3. test/test2: quentin (#4, 200 Bytes)
 


Dans le premier exemple, 'quentin' possède 2 fichiers dans test/. Il affiche donc 2.
Dans le second, quentin possède 2 fichiers dans test/, mais il affiche 6 car il a pris en compte le sous-dossier test/test2.

 


Pour l'instant, voici comment je procède :

 

J'ai créé une structure arbre pour représenter l'ensemble des fichiers / dossiers :

Code :
  1. typedef struct Leaf
  2. {
  3.     struct File *file;
  4.     struct Leaf *parent;     // pointeur vers le noeud père
  5.     struct Leaf *next;         // pointeur vers le noeud suivant au même niveau
  6.     struct Leaf *child;        // pointeur vers le fils
  7. } Leaf;
  8. typedef struct Tree
  9. {
  10.     Leaf *first;
  11. } Tree;
 

Après avoir parcouru tous les dossiers et sous dossier et stocké tous les fichiers dans l'arbre (avec les bonnes relations parent / child / next), je 'parse' le résultat.

 

J'ai réussi à faire l'exemple 1, c'est à dire sans la prise en compte des sous-dossiers ainsi :

Code :
  1. void parseTree (Tree *tree)
  2. {
  3.     if (tree == NULL)
  4.         printf("The tree is empty!n" );
  5.     else
  6.         parseTreeRec2 ((tree->first)->child, ((tree->first)->file)->fullname); // Je passe en paramètre le premier 'child' du tree, qui correspond au premier fichier du dossier 'racine', mais également le fullpath du dossier parent (ici, le dossier racine) (Ce 2ème paramètre sert juste pour l'affichage par la suite)
  7. }
  8. void parseTreeRec (Leaf *leaf, char *path)
  9. {
  10.     if (leaf != NULL)
  11.     {
  12.         // J'alloue une liste qui sera donc remplie d'utilisateur unique avec comme attribut un nombre de fichier et la taille totale
  13.         List *l;
  14.         l = malloc (sizeof (List));
  15.         initList (l);
  16.        
  17.         Leaf *current = leaf;
  18.         while (current != NULL)
  19.         {
  20.             // J'ajoute l'utilisateur du fichier parcouru (il y a une méthode pour vérifier la présence de cet utilisateur, auquel cas on met juste a jour les attributs 'nombre de fichiers' et 'taille totale'
  21.             addUser (l, (current->file)->owner,  1, (current->file)->size);
  22.             parseTreeRec2 (current->child, (current->file)->fullname);
  23.             current = current->next;
  24.         }
  25.         // Une fois le dossier est fini d'être parcouru, j'affiche la liste
  26.         printf ("%s: ", path);
  27.         displayList (l);
  28.     }
  29. }
 


Jusqu'ici, tout va bien. Maintenant, les choses se complique. Il faut que je puisse prendre en compte les sous-dossiers pour chaque dossier ...
J'ai pensé à passer une liste en paramètre à un fonction similaire à "parseTreeRec" qui se mettrait à jour avec les valeurs des sous dossiers. Seulement cela signifie qu'il me faut créer une liste par dossier et je ne vois pas comment faire cela en conservant la récursivité ...

 

J'espère ne pas avoir été trop "brouillon" ...

 

Par avance, Merci à ceux qui tenteront de me comprendre :whistle:


Message édité par Ydalb le 17-11-2010 à 18:57:04

---------------
:o
Reply

Marsh Posté le 17-11-2010 à 18:56:10   

Reply

Marsh Posté le 17-11-2010 à 19:24:33    

Quand tu va passer ta liste en paramètre, seul le pointeur sera envoyé à ta fonction, et chaque appel modifiera donc la même liste en mémoire.
Tu as beau avoir des appels récursifs, une seule liste est donc modifiée en prenant en compte les sous répertoires. Tu n'as pas de problèmes d'accès concurrent à cette liste car chaque appel à ta fonction de parcours d'arbre, récursif ou non, est séquentiel.


Message édité par h3bus le 17-11-2010 à 19:25:31

---------------
sheep++
Reply

Marsh Posté le 17-11-2010 à 20:00:41    

Merci pour ta réponse.
 
Je comprends ce que tu me dis et j'approuve, seulement après avoir passé une liste en paramètre au dossier racine, il faudra en faire de même pour chacun de ses sous-dossiers car je dois afficher également des résultats pour chacun de ses sous-dossiers (qui eux tiennent compte de leurs sous-dossiers, etc ...). Ce qui signifie 1 liste par dossier ..
Maintenant, je suis complètement perdu dans l'algo à employer pour réaliser cela ... Je pense que je passe trop de temps dessus et que je suis maintenant noyé :D


---------------
:o
Reply

Marsh Posté le 17-11-2010 à 20:36:55    

Mmhhh dans ce cas tu vas effectivement créer un liste par dossier et la libérer à chaque fin de fonction. De cette manière tu aura au maximum n listes en mémoire à un instant donné ou n est la profondeur maximale de ton arborescence.


---------------
sheep++
Reply

Marsh Posté le 17-11-2010 à 21:07:31    

Tu refais "du" ?
 
Bon courage !  :)

Reply

Marsh Posté le 17-11-2010 à 21:22:12    


 
Grosso modo :D


---------------
:o
Reply

Marsh Posté le 17-11-2010 à 21:22:49    

h3bus a écrit :

Mmhhh dans ce cas tu vas effectivement créer un liste par dossier et la libérer à chaque fin de fonction. De cette manière tu aura au maximum n listes en mémoire à un instant donné ou n est la profondeur maximale de ton arborescence.


 
Eh ben moi qui pensait avoir bientôt fini, me voilà rassurer :D


---------------
:o
Reply

Marsh Posté le 17-11-2010 à 21:36:02    

D'ailleurs, vous auriez un lien pour le code source de "du" histoire de me faire peur ? :D

 

EDIT: J'ai trouvé le code source de 'du' .. Erm .. J'aurais pas dû :D


Message édité par Ydalb le 17-11-2010 à 21:44:41

---------------
:o
Reply

Marsh Posté le 17-11-2010 à 21:53:50    

Code de du: http://www.koders.com/c/fid73D91B8 [...] CF10C.aspx
 
Jtrouve ça beaucoup plus simple que ce que tu fais...


---------------
sheep++
Reply

Marsh Posté le 17-11-2010 à 22:28:01    

Hm, j'ai pas le même code (je parle de celui que j'ai trouvé) ... :D


Message édité par Ydalb le 17-11-2010 à 22:28:13

---------------
:o
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed