生成“探索者树”在Java中有效(不使用递归)

发布于 2024-09-16 10:06:28 字数 904 浏览 3 评论 0原文

我有一个问题,可能与语言无关,但对于这个特定的实现,我使用的是 Java。列出目录中的文件夹是可能的,而且相对简单 - 使用如下函数:

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;
}

如您所见,这大量使用递归来评估文件系统,最终得到的是 DefaultMutableTreeNode 项目。

现在我的问题是 - 有没有更快的方法来做到这一点?一定有,因为这很慢。尝试在 / 上执行此操作,它会花费很长时间。然而,如果我使用 Nautilus 或内置的 Java 文件选择对话框,树就会立即呈现。

所以我的问题是 - 我怎样才能加快速度?

谢谢

I have a question which could be language-agnostic but for this particular implementation I'm using Java. It is possible and relatively trivial to list the folders in a directory - using a function like this:

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;
}

As you can see this makes heavy use of recursion to evaluate the filesystem and what you end up with is a tree of DefaultMutableTreeNode items.

Now my question is - is there a faster way to do this? There must be, because this is slow. Try executing this on / and it takes forever. Yet if I use say Nautilus or the built-in Java File selection dialog, the tree renders instantly.

So my question is - how can I speed this up?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

彼岸花ソ最美的依靠 2024-09-23 10:06:28

执行此操作的正常方法是首先仅读取单个目录。该顶级目录下的任何目录都不会立即被读取。相反,将在创建的目录树节点下插入一个虚拟节点。当用户展开目录节点时,程序会读取相关目录,然后用反映目录内容的节点替换虚拟节点。

The normal way to do this is to only read a single directory at first. Any directories under that top level directory will not be read immediately. Instead a dummy node will be inserted under the directory tree node that is created. When the user expands the directory node the program then reads the relevant directory and then replaces the dummy node with nodes that reflect the contents of the directory.

贪了杯 2024-09-23 10:06:28

看看这个例子
http://www.java2s.com/Code/Java/Swing- JFC/FileTree.htm
此树模型将为您的 jtree 提供文件系统结构。仅在扩展节点时才访问文件系统...并且最初是针对根节点。 ;)

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) {}


}

使用

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

此模型将防止您用 DefaultTreeNodes 填满内存,并最大限度地减少对底层文件系统的访问。

take a look at this example
http://www.java2s.com/Code/Java/Swing-JFC/FileTree.htm
this treemodel will provide the filesystem structure to your jtree. the file system is only accessed when expanding a node... and initially for the root node. ;)

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) {}


}

usage

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

this model will prevent you from filling up your memory with DefaultTreeNodes and minimizes the access to the underlying filesystem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文