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

Scilab Discussion :

Parcours récursif de répertoires


Sujet :

Scilab

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Parcours récursif de répertoires
    Bonjour,

    Je planche depuis quelque temps sur un problème Scilab, je me permet donc de poster sur ce forum en espérant bénéficier de vos conseils.

    Je souhaite mettre au point une fonction récursive à laquelle je passe en argument un chemin vers un répertoire. La fonction doit alors stocker dans une liste l'ensemble des chemins des fichiers (juste les fichiers, pas les répertoires) qu'elle trouvera en balayant le contenu de ce répertoire.

    Voici le code auquel je suis arrivé pour l'instant :

    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
    35
    36
    37
    // Fonction recursive de parcours de repertoires
    
    
    function liste_fichiers = parcours_repertoire(chemin_courant)    
        liste = [];
        // Test pour vérifier la présence du cractère '\' en fin de chemin
        taille_chaine = length(chemin_courant)
        if (part(chemin_courant,taille_chaine)~='\') then 
            chemin_courant = chemin_courant + '\';
        end
    
        fichiers = listfiles(chemin_courant);
        [nra,nca]=size(fichiers);
        
        for i=1:nra
            // On reconstitue le chemin entier avant de stocker
            // en effet listfiles ne renvoie que le nom relatif
            fichiers(i) = chemin_courant + fichiers(i);
    
            // Si le fichier est un répertoire, on relance le balayage de manière      récursive
            if isdir(fichiers(i))then
                liste_fichiers = parcours_repertoire(fichiers(i));
            else
                // Sinon on stocke simplement le chemin dans la liste à la suite ce qui précède
                liste(i) = fichiers(i);
                [nrb,ncb]=size(liste_fichiers);
                liste_fichiers(nrb+1)= fichiers(i);
            end 
        end
        
    endfunction
    
    // Appel de la fonction
    liste_fichiers = []
    chemin_repertoire = 'C:\Test'
    liste_fichiers = parcours_repertoire(chemin_repertoire)
    Mon cas de figure : Il y a deux répertoires contenant chacun un répertoire. Ces derniers comprennent des fichiers textes. Ce n'est biensur qu'un exemple des nombreux de cas de figures possible.

    Repertoire1->Repertoire11->Fichiers textes
    Repertoire2->Repertoire21->Fichier textes

    Le problème :

    Je me retrouve avec un liste qui contient bien le nombre d'éléments voulus. Par exemple 50 lignes pour 50 fichiers. Mais seuls les chemins du répertoire 21 sont écrites en fin de liste. Le début de liste contient des lignes vides.

    Liste_fichiers :
    []
    []
    []
    ...
    Repertoire2->Repertoire21->blabla1.txt
    Repertoire2->Repertoire21->blabla2.txt
    ...
    Repertoire2->Repertoire21->blablaN.txt

    J'imagine qu'il y a un problème de portée des variables... Je ne sais pas trop.
    Je ne comprend pas pourquoi seulement le dernier répertoire traité est affiché correctement. J'ai testé avec une vingtaine de répertoire et le problème reste le même, toujours le dernier répertoire affiché, et pour ceux d'avant, des lignes vides...

    Merci d'avance pour le coup de main!

  2. #2
    Membre habitué
    Homme Profil pro
    Ingénieur opto-électronique
    Inscrit en
    Avril 2010
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur opto-électronique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2010
    Messages : 129
    Points : 157
    Points
    157
    Par défaut
    Bonsoir.

    Je ne connais pas trop Scilab, manipulant plutôt Matlab, mais vu que ça se ressemble pas mal, voilà ce que je peux te conseiller:

    • D'abord vérifie les noms de tes variables, il y a une certaine incohérence et certaines sont utilisées sans être assignées:

      - Tu crées une variable fichiers:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      fichiers = listfiles(chemin_courant);
      - tu crées une variable liste_fichiers SI fichiers(i) est un dosser:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      if isdir(fichiers(i))then
                  liste_fichiers = parcours_repertoire(fichiers(i));
              else
      ...
      et dans le else en question, tu utilises liste_fichiers, qui risque de ne pas avoir été défini:

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      liste_fichiers(nrb+1)= fichiers(i);
      De ce fait, je suis même surpris que ton programme arrive à fonctionner.
    • Ensuite, ça existe sur Matlab, je suppose que ça existe aussi sur Scilab : La fonction 'size' te permet de prendre un second argument qui définit la dimension dont tu veux connaitre la taille. Tu pourrais donc simplement faire et ne pas assigner de variables inutilisées.
    • Enfin, quand tu fais une récurrence et rappelle ta fonction, tu ne concatène pas ta nouvelle liste à l'ancienne, ce qui fait que tes anciennes données sont perdues (ou que les nouvelles ne sont pas utilisées).



    Un exemple sous Matlab:

    main.m
    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
        clc
        chemin_courant = 'C:\Users\Olivier\Desktop\dir';
     
        i=1;
        liste=listing(chemin_courant); %listing initial
     
        while(1)
            if i>size(liste,2) %la boucle s'arrête quand on a atteint la fin de la liste
                break;
            end
     
            if isdir(char(liste(i)))    %si c'est un dossier
                liste=[liste listing(liste(i))]; %On liste ce dossier et on le colle à la liste déjà créée
                liste(i)=[]; %on supprime l'item en cours, c'était un nom de dossier et on ne voulait que les fichiers
            else
                i=i+1;  %si c'est un fichier, on n'y touche pas et on passe à l'item suivant
            end
        end
     
        for i=1:size(liste,2)
            disp(liste(i))
        end
    listing.m
    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
    function liste=listing(chemin_courant)
     
    if ~strcmp(chemin_courant(end),'\') %Test pour vérifier la présence du caractère '\' en fin de chemin
        chemin_courant = strcat(chemin_courant,'\');
    end
     
    chemin_courant=char(chemin_courant);
     
    fichiers=dir(chemin_courant);%récupération des fichiers/dossiers situés dans chemin_courant
    fichiers=fichiers(3:end);%suppression des dossiers [.] et [..] (racine et dossier parent si mes souvenirs sont bons)
     
    liste=([]);
    for i=1:size(fichiers,1)
        liste{i}=strcat(chemin_courant,fichiers(i).name); %enregistrement des fichiers dans une structure, pour éviter les problemes de taille des strings.
    end

    Résultat:
    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
        'C:\Users\Olivier\Desktop\dir\dir1\txt1.txt'
     
        'C:\Users\Olivier\Desktop\dir\dir1\txt2avecuntitrepluslong.txt'
     
        'C:\Users\Olivier\Desktop\dir\dir1\txt3.txt'
     
        'C:\Users\Olivier\Desktop\dir\dir2nompluslong\txt1.txt'
     
        'C:\Users\Olivier\Desktop\dir\dir2nompluslong\txt2.txt'
     
        'C:\Users\Olivier\Desktop\dir\dir2nompluslong\txt3.txt'
     
        'C:\Users\Olivier\Desktop\dir\dir3\txt1.txt'
     
        'C:\Users\Olivier\Desktop\dir\dir3\txt2.txt'
     
        'C:\Users\Olivier\Desktop\dir\dir3\txt3.txt'

  3. #3
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 884
    Points
    52 884
    Par défaut
    Citation Envoyé par Myrne Voir le message

    main.m
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            if isdir(char(liste(i)))    %si c'est un dossier

    CHAR est inutile ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            if isdir(liste{i})    %si c'est un dossier
    Citation Envoyé par Myrne Voir le message

    listing.m
    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
    function liste=listing(chemin_courant)
     
    if ~strcmp(chemin_courant(end),'\') %Test pour vérifier la présence du caractère '\' en fin de chemin
        chemin_courant = strcat(chemin_courant,'\');
    end
     
    chemin_courant=char(chemin_courant);
     
    fichiers=dir(chemin_courant);%récupération des fichiers/dossiers situés dans chemin_courant
    fichiers=fichiers(3:end);%suppression des dossiers [.] et [..] (racine et dossier parent si mes souvenirs sont bons)
     
    liste=([]);
    for i=1:size(fichiers,1)
        liste{i}=strcat(chemin_courant,fichiers(i).name); %enregistrement des fichiers dans une structure, pour éviter les problemes de taille des strings.
    end
    Voir la : Comment concaténer le nom d'un fichier et celui d'un répertoire ?
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Tout d'abord merci pour ta réponse.

    Ton système est astucieux, tu n'as pas besoin d'utiliser la récursivité, elle est implicite en fait.

    J'ai aussi essayé de déclarer une nouvelle variable dans ma fonction avec une boucle qui fait le travail d'une fonction de concaténation mais ça n'a pas supprimé le problème.

    Je vais aussi me renseigne sur les arguments de la fonction listfiles(), je crois qu'elle peut prendre un script en paramètre. Si j'arrive à l'écrire, je devrais failement pouvoir lister tous les fichier avec une commande de type DIR.

    J'aimerais bien comprendre ce problème de déclration de variable.
    J'ai déclaré listes_fichiers avant l'appel à la fonction pour qu'elle soit globale et qu'elle ne s'écrase pas à chaque tour de fonction. Je ne sais pas si c'est cohérent...

  5. #5
    Membre habitué
    Homme Profil pro
    Ingénieur opto-électronique
    Inscrit en
    Avril 2010
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur opto-électronique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2010
    Messages : 129
    Points : 157
    Points
    157
    Par défaut
    Merci Dut pour ces précisions, moi et la manipulation de strings/char/cell, ça fait deux...


    Suite aux remarques de Dut, tu peux aller voir ce que fait la fonction fullfile pour ta concaténation, cela devrait t'aider.

    La description de dir et de listfiles devrait aussi te permettre de voir ce que tu peux faire exactement.

    Quant à ton problème de variables, quand bien même ta variable serait déclarée en global, si tu écris "ta_variable=truc", et bien le contenu de ta_variable va être effacé, remplacé par "truc". Si tu veux conserver ce qu'il y avait déjà dessus, il faut que tu ajoutes "truc" à la fin de ta_variable.

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Mais ici je le prends compte il me semble!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    liste(i) = fichiers(i);
    [nrb,ncb]=size(liste_fichiers);
    liste_fichiers(nrb+1)= fichiers(i);
    C'est une sorte de fonction de concaténation maison. Je ne comprend pas pourquoi seulement le dernier répertoire lu et traité fonctionne chez moi.

  7. #7
    Membre habitué
    Homme Profil pro
    Ingénieur opto-électronique
    Inscrit en
    Avril 2010
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur opto-électronique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2010
    Messages : 129
    Points : 157
    Points
    157
    Par défaut
    Ici tu ne le prends pas en compte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if isdir(fichiers(i))then
                liste_fichiers = parcours_repertoire(fichiers(i));
    Quand tu rencontres un répertoire, tu effaces liste_fichiers et le remplace par le contenu du répertoire que tu viens d'explorer.

    Et je pense que ça doit expliquer le fait que seul le dernier repertoire est listé, tous les autres ont été effacés quand tu as trouvé le dernier répertoire.
    Quant aux espaces blancs, je pense que ça vient de l'incrémentation de i dans ta boucle for, tu enregistres ton fichier à la ligne i, mais les lignes 1 à i-1 sont probablement vides.

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Bon malgré tes conseils, je n'arrive pas à obtenir ce que je souhaite... Et je ne peux pas me permettre d'y passer plus de temps.

    La récursivité se fait mal et même si maintenant j'arrive à obtenir les contenus des deux répertoires, ils sont disposés de manière anarchique et la liste qui les stocke est entrecoupée de blancs.

    J'ai trouvé une solution alternative qui fonctionne même si elle est moins élégante.
    Je passe une commande dir à la fonction dos() avec les paramètres /s et /b pour lister les fichiers. Ca marche très bien même si il faut du coup respecter la convention de nommage DOS (pas d'espaces et pas de caractères spéciaux).

    Je laisse un peu mon post au cas ou quelqu'un aie le courage d'y passer un peu de temps.

    Encore merci!

  9. #9
    Membre habitué
    Homme Profil pro
    Ingénieur opto-électronique
    Inscrit en
    Avril 2010
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur opto-électronique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2010
    Messages : 129
    Points : 157
    Points
    157
    Par défaut
    ta fonction listfiles liste aussi les dossiers parent et racine. La notation est du type . ou .. et il n'est pas impossible que tes blancs soient dus à ça.

    Quant à l'ordre des fichiers, tu peux toujours faire un tri alphabétique dessus pour le remettre dans le bon ordre.

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

Discussions similaires

  1. [Virtual Pascal] Parcours récursif de répertoires
    Par Alcatîz dans le forum Codes sources à télécharger
    Réponses: 0
    Dernier message: 16/11/2010, 21h56
  2. Réponses: 1
    Dernier message: 10/11/2008, 16h38
  3. Parcours récursif des répertoires
    Par Prosis dans le forum Langage
    Réponses: 5
    Dernier message: 29/01/2008, 20h39
  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. [DEBUTANT MFC] Parcours d'un répertoire
    Par gwendo dans le forum MFC
    Réponses: 3
    Dernier message: 15/09/2005, 17h14

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