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

Composants VCL Delphi Discussion :

idFTP.DirectoryListing récursif + TreeNode


Sujet :

Composants VCL Delphi

  1. #1
    Membre du Club Avatar de fredfred
    Inscrit en
    Septembre 2002
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 161
    Points : 54
    Points
    54
    Par défaut idFTP.DirectoryListing récursif + TreeNode
    Salut à tous,

    Je cherche à charger tous les répertoires et sous-répertoires d'un site FTP dans un TreeNode.
    Pour cela j'ai fait une procédure récursive :

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    var
      ListDir : array[0..10] of TIdFTPListItems;
      Node: array[0..10] of TTreeNode;
     
    procedure TFProcess.B_ChargeRepClick(Sender: TObject);
    begin
          treeview1.items.Clear;
     
          node[0]:=treeview1.Items.AddObject(nil,'/', ImageList1);
     
          // Charge les répertoires distants
          List(nil);
          Charge_FTP_Rep(1);
    end;
     
    procedure TFProcess.Charge_FTP_Rep(PNiv :integer);
    var i:integer;
         Nb_Dir :integer;
    begin
     
      with IdFTP1 do
      begin
        // Charge la liste des répertoires et des fichiers du répertoire courant
        List(nil);
        ListDir[PNiv] := DirectoryListing;
     
        if ListDir[PNiv].Count > 0 then
        begin
          // compte la liste des répertoires dans le répertoire courant
          Nb_Dir:=0;
          for i:=0 to ListDir[PNiv].Count - 1 do
            if (ListDir[PNiv].Items[i].ItemType = ditDirectory) then
              Inc(Nb_Dir);
     
          // S'il y a au moins un répertoire, on récupère les noms
          if Nb_Dir > 0 then
          begin
            for i:=0 to ListDir[PNiv].Count - 1 do
            begin
              // Si c'est un répertoire
              if (ListDir[PNiv].Items[i].ItemType = ditDirectory) then
              begin
                // Ajoute le répertoire dans l'arborescence
                Node[PNiv]:=treeview1.Items.AddChildObject(node[PNiv-1], ListDir[PNiv].Items[i].FileName, ImageList1);
     
                // Recherche les sous-répertoires du répertoire courant
                ChangeDir(ListDir[PNiv].Items[i].FileName);
                Charge_FTP_Rep(PNiv+1);
                ChangeDirUp;
     
              end; // if ditDirectory
            end; // for i
          end; // if Nb_Dir > 0
     
         end; // if ListDir[PNiv].Count > 0
     
      end; // with IdFTP1
    end;
    La structure du FTP est la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    /
         Cartes
              Impression
         Immo
              Photos
              Vignettes
         PH
              Save
    A l'exécution, dans mon TreeNode j'obtiens :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    +/
          +Cartes
                   Impression

    Tout se passe bien jusqu'au sous-rep Impression, mais lorsque la fonction revient au PNiv=1 (le /, pour continuer dans Immo), le ListDir[1].Count est passé à 0, alors qu'il était bien à 3 au départ, et donc déclenche une erreur d'indice hors-limite ????

    Avec des Showmessage, je vois que le ListDir[1] est réinitialisé dès l'appel de la procédure avec PNiv=2, ce qui n'est pas normal vu que c'est un tableau global, et non local, ses valeurs devraient être conservées si on change d'indice.

    Si je ne mets pas List(nil) en début de fonction, alors le programme va chercher un répertoire /cartes/cartes, qui bien entendu n'existe pas, donc erreur.

    J'ai vu d'autres posts sur des problèmes similaires, mais je n'ai pas trouvé de solution à mon problème.

    Quelqu'un voit-il pourquoi ListDir[] est réinitialisé à vide lorsque la procédure descend au niveau suivant ??
    Postes Dév : W7 SP1 / Windev 21 / Delphi 7 Entreprise
    Serveur : W2k12 SP1 + SQL 2014 RC2
    Connexion : OLE.DB

  2. #2
    Membre expérimenté

    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 685
    Points : 1 608
    Points
    1 608
    Par défaut
    Ton code est bizarre... Si tu tiens à faire une exploration récursive en manipulant le DirectoryListing, tu peux utiliser une procédure comme celle-ci :

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    procedure TForm1.ScanFTPDir(AFTPClient: TIdFTP; ARoot: string; AStringList : TStringList);
    var
      i : integer;
      LFoldersToExplore : TSTringList;
     
      function SlashIfNeeded(const APath : string) : string;
      begin
          if Length(APath)>1 then
          begin
            if APath[Length(APath)] <> '/' then
              Result := APath + '/'
            else
              Result := APath;
          end else
            Result := '/';
      end;
     
    begin
      with AFTPClient do
      begin
        try
          ChangeDir(ARoot);
          try
            AFTPClient.List(nil); //Pour remplir la prop. "DirectoryListing"
          finally
            {Bloc pour se protéger d'une exception éventuelle
             liée à la fermeture du canal de données}
             if not Connected then
               Connect();
          end;
        except
          raise Exception.Create(Format('Répertoire introuvable : %s',[ARoot]));
        end;
        LFoldersToExplore := TStringList.Create;
        try
          for i:= 0 to Pred(DirectoryListing.Count) do
          begin
              if not (DirectoryListing[i].ItemType=ditDirectory) then
              begin
                {Des fichiers à ajouter}
                 AStringList.Add(SlashIfNeeded(ARoot)+DirectoryListing[i].FileName);
                 //Memo1.Lines.Add('Ajoute : ' + SlashIfNeeded(ARoot)+DirectoryListing[i].FileName);
              end else {Chercher de manière groupée les fichiers à ajoiter}
               if (DirectoryListing[i].FileName<>'.') and (DirectoryListing[i].FileName<>'..') then
                 LFoldersToExplore.Add(SlashIfNeeded(ARoot)+DirectoryListing[i].FileName)
          end;
          {On explore maintenant chaque dossier détecté}
          for i:=0 to Pred(LFoldersToExplore.Count) do
          begin
            //Memo1.Lines.Add('Explore : ' + LFoldersToExplore[i]);
            ScanFTPDir(AFTPClient,LFoldersToExplore[i],AStringList); {Relancer récursivement}
            ChangeDir(ARoot); {Revenir au répertoire initial}
          end;
        finally
            LFoldersToExplore.Free; {Libérer la liste}
        end;
      end;
    end;
    Encore plus simple : utiliser List('*',False) pour obtenir les dossiers et List('*.',False) pour les fichiers, puis directement manipuler les résultats.
    "It's more fun to compute !"

  3. #3
    Membre du Club Avatar de fredfred
    Inscrit en
    Septembre 2002
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 161
    Points : 54
    Points
    54
    Par défaut
    ça marche super bien. Merci.

    Pour info, pourquoi trouves-tu mon code "bizarre" ?


    Mais bon, mintenant j'ai un autre problème, je n'arrive pas à obtenir la liste des textes du neoud sélectionné et de ses parents.

    pas exemple, si je clique sur 'Vignettes' (cf. mon premier post), je n'obtiens que immo/photo, c.a.d. les noeuds au-dessus, mais pas ceux de gauche en remontant l'arborescence, alors que je voudrais '/immo4/vignettes'

    j'ai essayé de jongler avec des getprev, getprevvisible, getprevchild, etc... sans succès.
    Postes Dév : W7 SP1 / Windev 21 / Delphi 7 Entreprise
    Serveur : W2k12 SP1 + SQL 2014 RC2
    Connexion : OLE.DB

  4. #4
    Membre du Club Avatar de fredfred
    Inscrit en
    Septembre 2002
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 161
    Points : 54
    Points
    54
    Par défaut
    ça y est, j'ai trouvé :

    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
     
    procedure TFProcess.TreeView1Change(Sender: TObject; Node: TTreeNode);
    var I :Integer;
        SelNode, CurNode, ParentNode:TTreeNode;
        Rep :string;
    begin
      SelNode :=TreeView1.Selected;
      Rep:=SelNode.text;
      CurNode:=SelNode;
     
      for i:= SelNode.Level downto 1 do
      begin
        ParentNode :=CurNode.Parent;
     
        // Tant qu'on est pas remonté à la racine, on préfixe chaque répertoire d'un /
        if i>1 then
          rep:='/'+rep;
     
        Rep:=ParentNode.text+Rep;
     
        CurNode:=ParentNode;
      end;
    end;
    mais ça me semble quand même un peu tordu.
    peut-être existe-t'il une manière plus simple ?
    Postes Dév : W7 SP1 / Windev 21 / Delphi 7 Entreprise
    Serveur : W2k12 SP1 + SQL 2014 RC2
    Connexion : OLE.DB

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

Discussions similaires

  1. Edition zone texte du libelle d'un TREENODE / Evenement Echa
    Par bigbagisbigbag dans le forum C++Builder
    Réponses: 8
    Dernier message: 03/03/2005, 18h25
  2. Script pour effacement récursif
    Par Filippo dans le forum Scripts/Batch
    Réponses: 3
    Dernier message: 09/01/2005, 17h10
  3. Indy IdFTP Upload
    Par djshaker dans le forum Web & réseau
    Réponses: 10
    Dernier message: 03/11/2004, 13h37
  4. XPATH XSL Récursif (très débutant!)
    Par luta dans le forum XSL/XSLT/XPATH
    Réponses: 14
    Dernier message: 24/08/2004, 10h04
  5. Indy FTP (idFTP) faire une barre de progress de transfert
    Par Harry dans le forum Web & réseau
    Réponses: 4
    Dernier message: 09/07/2004, 13h15

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