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 de dossier récursif


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Janvier 2011
    Messages
    34
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 34
    Par défaut Parcours de dossier récursif
    Bonjour, je travaille actuellement sur un projet de sauvegarde de fichier sous GNU/Linux, pour le moment, je souhaite crée un fichier qui sauvegarde le nom de tous les répertoire, sous répertoire et fichier ainsi que leur md5sum dans un fichier.
    J'ai le code suivant
    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
     
    void dumpFile(string directory, ofstream& output){
       DIR *dir = NULL;
       struct dirent *file = NULL;
       if((dir = opendir(directory.c_str())) == NULL){
     
       }
       while((file = readdir(dir)) != NULL){
          if(strcmp(file->d_name, ".") && strcmp(file->d_name, "..")){
             if(file->d_type == DT_DIR){ // Folder
    	   dumpFile(directory.append("/").append(file->d_name), output);
    	 }else{
    	    cout << directory << "/" << file->d_name << endl; // Just to see what is the problem
                output << file->d_name << endl << md5sum(directory, file->d_name) << endl; // Write the result on 2 lines (first the name, then de md5
    	 }
          }
       }
     
       closedir(dir);
     
    }
    Donc, si le dossier ne possède que des fichier, ou que je supprime la ligne de récursivité (le if), cela fonctionne parfaitement, mais là, elle bloque et je ne comprend vraiment pas pourquoi.
    Type d'erreur :
    directory : /home/user/Bureau
    Fichier : test.dump, test
    Sous dossier : python
    sous fichier : aucun

    /home/user/Bureau/test.dump
    /home/guillaume/Bureau/python/test
    terminate called after throwing an instance of 'std::bad_alloc'
    what(): std::bad_alloc
    Abandon

    Ce qui est normal, étant donnée que le fichier test n'existe pas dans le dossier python, mais est sur le bureau.

    Merci pour votre aide.

  2. #2
    Membre émérite
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Par défaut
    Pourquoi ne pas utiliser boost.filesystem ?

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 412
    Par défaut
    Citation Envoyé par Ekleog Voir le message
    Pourquoi ne pas utiliser boost.filesystem ?
    parce que boost est pas une lib dans la stl et que donc réduis la portabilliter, c'est donc une autre sujet mai soumettre l'idée de la lib est toujours bonne

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par panthere noire Voir le message
    parce que boost est pas une lib dans la stl et que donc réduis la portabilliter
    Certes, boost n'est pas utilisable partout. Mais dirent ou readdir ne font pas partie non plus de la bibliothèque standard. Et donc en l'occurrence, utiliser boost.filesystem accroit probablement la portabilité par rapport à utiliser des fonctions spécifiques à un OS.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 71
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
       while((file = readdir(dir)) != NULL){
          if(strcmp(file->d_name, ".") && strcmp(file->d_name, "..")){
             if(file->d_type == DT_DIR){ // Folder
    	   dumpFile(directory.append("/").append(file->d_name), output);
    	 }else{
    	    cout << directory << "/" << file->d_name << endl; // Just to see what is the problem
                output << file->d_name << endl << md5sum(directory, file->d_name) << endl; // Write the result on 2 lines (first the name, then de md5
    	 }
          }
       }
    Je pense que le scénario suivant est possible:

    tu as un dossier D, dans lequel tu as:
    - un dossier d1
    - un fichier f

    Au premier passage dans ta boucle, tu tombes sur d1, qui est un dossier donc tu rentres dans le if.
    Dans le if, tu appends d1 à D. A mon avis, le souci se trouve là. Ca n'a pas juste concaténé les chaînes et renvoyé une copie du résultat. A mon avis, ça a modifié ta variable directory. Donc tu te retrouves avec directory qui vaut "D/d1"

    du coup, après avoir traité le contenu de ton if, au deuxième passage dans ta boucle while, tu trouves le fichier f (normal) mais ta variable directory vaut alors D/d1.

    Et donc tu cherches D/d1/f, qui n'existe pas.

    Je te sugggère ce lien qui montre bien que string::append renvoie bien une ref et non une copie:

    http://www.cplusplus.com/reference/s...string/append/

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 412
    Par défaut
    Citation Envoyé par YoshioToutou Voir le message
    Bonjour, je travaille actuellement sur un projet de sauvegarde de fichier sous GNU/Linux, pour le moment, je souhaite crée un fichier qui sauvegarde le nom de tous les répertoire, sous répertoire et fichier ainsi que leur md5sum dans un fichier.
    J'ai le code suivant
    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
     
    void dumpFile(string directory, ofstream& output){
       DIR *dir = NULL;
       struct dirent *file = NULL;
       if((dir = opendir(directory.c_str())) == NULL){
     
       }
       while((file = readdir(dir)) != NULL){
          if(strcmp(file->d_name, ".") && strcmp(file->d_name, "..")){
             if(file->d_type == DT_DIR){ // Folder
    	   dumpFile(directory.append("/").append(file->d_name), output);
    	 }else{
    	    cout << directory << "/" << file->d_name << endl; // Just to see what is the problem
                output << file->d_name << endl << md5sum(directory, file->d_name) << endl; // Write the result on 2 lines (first the name, then de md5
    	 }
          }
       }
     
       closedir(dir);
     
    }
    Donc, si le dossier ne possède que des fichier, ou que je supprime la ligne de récursivité (le if), cela fonctionne parfaitement, mais là, elle bloque et je ne comprend vraiment pas pourquoi.
    Type d'erreur :
    directory : /home/user/Bureau
    Fichier : test.dump, test
    Sous dossier : python
    sous fichier : aucun

    /home/user/Bureau/test.dump
    /home/guillaume/Bureau/python/test
    terminate called after throwing an instance of 'std::bad_alloc'
    what(): std::bad_alloc
    Abandon

    Ce qui est normal, étant donnée que le fichier test n'existe pas dans le dossier python, mais est sur le bureau.

    Merci pour votre aide.


    5 problème vont venir
    1.-les lien,(ton problème actuel)
    2.- les montage (mount) ,
    3.-les fichier qui on pas les bon droit
    4.- les fichier de grande taille pour le md5
    5.- la récursivité dans /proc


    Pour ton problème il faut regarder du coter de lstat et stat si mes souvenir son bon

    j'ai déjà fait ce type de code, je voudrai juste voir le tien pour comparer,car j'ai été et suis toujours avec des problème dans /proc (donc pas aux points quoi)

    je te conseil de faire une fois ta fonction terminée, des essais sur / et des répertoires avec tout les droit possibles, tu verras c'est juste une question de patience.
    une fois que t'arrive faire ton / de A a Z avec les md5, il faudrai voir la quantité de fichier , car certain disque monte a 2 To, et encore avec linux tu peux monter autant de disque que tu veux
    tu peux vite te retrouver avec un fichier texte de 50 mg
    vala

  7. #7
    Membre averti
    Inscrit en
    Janvier 2011
    Messages
    34
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 34
    Par défaut
    Merci pour vos réponse, en effet, append ne fait pas une copie, je suis donc passé par une variable intermédiaire, et cela fonctionne parfaitement bien.
    J'ai eu des problèmes avec le symlink, que j'ai géré en rajoutant une condition dans le if (sale mais fonctionnel).
    Pour une plus grande clarté et portabilitée du code, il faudrait en effet utiliser les stats, ce que je n'ai pas mis en place car je ne dois lancer cela uniquement dans dans le /var/www donc a priopri pas d'éléments trop fantaisistes.
    Pour le code (si jamais ca interesse quelqu'un).
    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 dumpFile(string directory, ofstream& output){
       string path="";
       DIR *dir = NULL;
       struct dirent *file = NULL;
       if((dir = opendir(directory.c_str())) == NULL){
         return 1;
       }
       while((file = readdir(dir)) != NULL){
          if(strcmp(file->d_name, ".") && strcmp(file->d_name, "..")){
             if(file->d_type == DT_DIR || file->d_type == DT_LNK){
    	   path= "";
    	   dumpFile(path.append(directory).append("/").append(file->d_name), output);
    	 }else{
                output << file->d_name << endl << md5sum(directory, file->d_name) << endl; // Write the result on 2 lines (first the name, then de md5
    	 }
          }
       }
     
       closedir(dir);
      return 0;
    }

Discussions similaires

  1. Réponses: 2
    Dernier message: 26/02/2009, 11h23
  2. Agrandir fenêtre de parcours de dossier
    Par nicolas_151 dans le forum VBA Access
    Réponses: 4
    Dernier message: 07/07/2008, 11h33
  3. Parcours de dossier
    Par amateurc dans le forum Ada
    Réponses: 5
    Dernier message: 19/06/2008, 22h37
  4. Droits pour le parcours de dossier
    Par gazelle dans le forum Langage
    Réponses: 2
    Dernier message: 10/06/2007, 18h25

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