2010-08-30 13 views
4

J'ai une question qui pourrait être langue-agnostique mais pour cette implémentation particulière, j'utilise Java. Il est possible et à la liste relativement triviale les dossiers dans un répertoire - en utilisant une fonction comme ceci:Générer "arbre de l'explorateur" en Java efficacement (ne pas utiliser la récursion)

private DefaultMutableTreeNode GenerateFSTree(File f) 
{ 
    int i = 0; 
    File[] Children = f.listFiles(); 

    DefaultMutableTreeNode x = new DefaultMutableTreeNode(f.getName()); 

    if (Children != null) 
    { 
     for (i = 0; i < Children.length; i++) 
     { 
      File f_cur = Children[i]; 
      if (
      f_cur.isDirectory() && 
      (this.DisplayHidden || !f_cur.isHidden()) 
      ) 
      { 
       x.add(GenerateFSTree(f_cur)); 
      } 
     } 
    } 

    return x; 
} 

Comme vous pouvez le voir fait un usage intensif de la récursivité pour évaluer le système de fichiers et que vous vous retrouvez avec un arbre de DefaultMutableTreeNode articles. Maintenant, ma question est - y at-il un moyen plus rapide de faire cela? Il doit y avoir, parce que c'est lent. Essayez d'exécuter ceci sur / et cela prend une éternité. Pourtant, si j'utilise dire Nautilus ou la boîte de dialogue de sélection de fichiers Java intégrée, l'arbre rend instantanément.

Donc, ma question est - comment puis-je accélérer cela?

Merci

+3

Je suppose que cette "stabilité" de Nautilus ou quoi que ce soit vient, parce que l'arbre est seulement chargé partiellement (par exemple ce que vous voyez dans ce moment). Mais c'est juste une supposition. – cyphorious

+1

Est-ce que cela fonctionne même? Jamais entendu parler de la récursivité de la queue? –

+2

J'imagine que la boîte de dialogue de sélection de fichier Java est paresseuse, littéralement. Pour afficher une boîte de dialogue standard de "sélection de fichier", vous n'avez qu'à afficher les parents (récursivement) de l'emplacement actuel et du contenu de l'emplacement actuel, et non l'intégralité de l'arborescence du système de fichiers. Donc, c'est probablement en utilisant les mêmes API que vous, juste en les exécutant quand il le faut. –

Répondre

2

jeter un oeil à cet exemple http://www.java2s.com/Code/Java/Swing-JFC/FileTree.htm
this treemodel fournira la structure du système de fichiers à votre jtree. le système de fichiers n'est accessible que lors de l'expansion d'un nœud ... et initialement pour le nœud racine. ;)

class FileTreeModel implements TreeModel { 
    protected File root; 
    public FileTreeModel(File root) { this.root = root; } 

    public Object getRoot() { return root; } 

    public boolean isLeaf(Object node) { return ((File)node).isFile(); } 

    public int getChildCount(Object parent) { 
     String[] children = ((File)parent).list(); 
     if (children == null) return 0; 
    return children.length; 
    } 

    public Object getChild(Object parent, int index) { 
     String[] children = ((File)parent).list(); 
     if ((children == null) || (index >= children.length)) return null; 
    return new File((File) parent, children[index]); 
    } 

    public int getIndexOfChild(Object parent, Object child) { 
     String[] children = ((File)parent).list(); 
     if (children == null) return -1; 
      String childname = ((File)child).getName(); 
      for(int i = 0; i < children.length; i++) { 
       if (childname.equals(children[i])) return i; 
      } 
      return -1; 
    } 

    public void valueForPathChanged(TreePath path, Object newvalue) {} 

    public void addTreeModelListener(TreeModelListener l) {} 
    public void removeTreeModelListener(TreeModelListener l) {} 


} 

utilisation

Jtree tree = new JTree(new FileTreeModel(new File("/"))); 

ce modèle vous empêchera de remplir votre mémoire avec DefaultTreeNodes et réduit l'accès au système de fichiers sous-jacent.

4

La manière habituelle de procéder est de ne lire qu'un seul répertoire au début. Tous les répertoires sous ce répertoire de premier niveau ne seront pas lus immédiatement. À la place, un noeud factice sera inséré sous le noeud de l'arborescence de répertoires créé. Lorsque l'utilisateur développe le noeud de répertoire, le programme lit ensuite le répertoire approprié, puis remplace le noeud factice par des noeuds qui reflètent le contenu du répertoire.