C#中 - 如何改进本"文件浏览器"启动速度?浏览器、速度、文件、QUOT

2023-09-11 23:24:05 作者:烦。

我填充用C#中的文件浏览器的解决方案。这是我的code:

I'm populating a "file explorer" solution by using c#. Here's my code:

namespace NIXplorer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

    TreeNode root = new TreeNode("Desktop");
    TreeNode doc = new TreeNode("My Documents");
    TreeNode comp = new TreeNode("My Computer ");
    TreeNode drivenode;
    TreeNode filenode;
    DirectoryInfo dir;
    string path = "";

    private void Form1_Load(object sender, EventArgs e)
    {
        listView1.LabelEdit = true;
        listView1.FullRowSelect = true;
        listView1.Sorting = SortOrder.Ascending;
        treeView1.Nodes.Add(root);
        root.ImageIndex = 0;
        doc.ImageIndex = 1;
        comp.ImageIndex = 2;
        treeView1.Nodes.Add(doc);
        treeView1.Nodes.Add(comp);
        GetDrives();
    }

    private void GetDrives()
    {
        DriveInfo[] drive = DriveInfo.GetDrives();
        foreach (DriveInfo d in drive)
        {
            drivenode = new TreeNode(d.Name);
            dir = d.RootDirectory;
            comp.Nodes.Add(drivenode);
            //drivenode.ImageIndex = 3;
            switch (d.DriveType)
            {
                case DriveType.CDRom:
                    drivenode.ImageIndex = 5;
                    break;
                //case DriveType.Fixed:
                //    drivenode.ImageIndex = 1;
                //    break;
                case DriveType.Removable:
                    drivenode.ImageIndex = 8;
                    break;
                //case DriveType.NoRootDirectory:

                //    drivenode.ImageIndex = 5;
                //    break;
                case DriveType.Network:
                    drivenode.ImageIndex = 6;
                    break;
                default:
                    drivenode.ImageIndex = 7;
                    break;
            }
            getFilesAndDir(drivenode, dir);
        }
    }

    private void getFilesAndDir(TreeNode node, DirectoryInfo dirname)
    {
        try
        {
            foreach (FileInfo fi in dirname.GetFiles())
            {
                filenode = new TreeNode(fi.Name);
                filenode.Name = fi.FullName;
                //filenode.ImageIndex = 5;
                getFileExtension(filenode.Name);
                node.Nodes.Add(filenode);
            }
            try
            {
                foreach (DirectoryInfo di in dirname.GetDirectories())
                {
                    TreeNode dirnode = new TreeNode(di.Name);
                    dirnode.ImageIndex = 4;
                    dirnode.Name = di.FullName;
                    node.Nodes.Add(dirnode);
                    getFilesAndDir(dirnode, di); //Recursive Functioning
                }
            }
            catch (Exception e1)
            {
            }
        }
        catch (Exception e1)
        {
        }
    }

    private void getFileExtension(string filename)
    {
        switch (Path.GetExtension(filename))
        {
            case ".txt":
                filenode.ImageIndex = 17;
                break;
            case ".rtf":
                filenode.ImageIndex = 16;
                break;
            case ".doc":
            case ".docx":
                filenode.ImageIndex = 9;
                break;
            case ".html":
            case ".htm":
                filenode.ImageIndex = 13;
                break;
            case ".rar":
            case ".zip":
                filenode.ImageIndex = 10;
                break;
            case ".exe":
                filenode.ImageIndex = 12;
                break;
            case ".mp3":
            case ".wma":
            case ".flac":
            case ".m4a":
                filenode.ImageIndex = 11;
                break;
            case ".mp4":
            case ".flv":
            case ".mkv":
            case ".webm":
                filenode.ImageIndex = 18;
                break;
            case ".ico":
            case ".png":
            case ".jpg":
            case ".jpeg":
            case ".psd":
                filenode.ImageIndex = 14;
                break;
            default:
                filenode.ImageIndex = 15;
                break;
        }
    }

    private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
    {
        try
        {
            listView1.Items.Clear();
            TreeNode selectednode = e.Node;
            treeView1.SelectedNode.ImageIndex = e.Node.ImageIndex;
            selectednode.Expand();
            comboBox1.Text = selectednode.FullPath;
            if (selectednode.Nodes.Count > 0)
            {
                foreach (TreeNode n in selectednode.Nodes)
                {
                    ListViewItem lst = new ListViewItem(n.Text, n.ImageIndex);
                    lst.Name = n.FullPath.Substring(13);
                    //MessageBox.Show("List Node : " + lst.Name);
                    listView1.Items.Add(lst);
                }
            }
            else
            {
                listView1.Items.Add(selectednode.FullPath, selectednode.Text, selectednode.ImageIndex);
            }
        }
        catch (Exception e1)
        {
        }
    }
}
}

我建立这个解决方案在VS2012该算法似乎不是最好的选择的原因,每次我调试此解决方案,它需要像超过1或2分钟,开始......这真的不好......希望你们能帮助一个更好的解决方案或算法?这会是很大的。在此先感谢!

I build this solution in VS2012 and this algorithm seems not the best choice 'cause everytime i debug this solution, it takes like more than 1 or 2 minutes to start ... this really bad... Hope you guys can help with a better solution or algorithm ? That'd be great. Thanks in advance !

推荐答案

加载所有的目录和文件是昂贵的IO操作。不会加载一切,当没有必要。用户不会看到一切所有的时间。

Loading all the directories and files are expensive IO operations. don't load everything when there is no need. user is not going to view everything all the time.

我会建议你来填充的需求。事情是这样的。

I'll suggest you to populate on demand. Something like this.

    class FileSystemObject
    {
        public FileSystemInfo FileSystemInfo;
        public FileSystemObjectType ObjectType;
        public bool SubNodesLoaded;
    }

    enum FileSystemObjectType
    {
        File = 1,
        Directory = 2
    }

    private void GetDrives()
    {
        DriveInfo[] drive = DriveInfo.GetDrives();
        foreach (DriveInfo d in drive)
        {
            drivenode = new TreeNode(d.Name);
            dir = d.RootDirectory;
            drivenode.Tag = new FileSystemObject { FileSystemInfo = dir, ObjectType = FileSystemObjectType.Directory };
            comp.Nodes.Add(drivenode);
            //drivenode.ImageIndex = 3;
            switch (d.DriveType)
            {
                case DriveType.CDRom:
                    drivenode.ImageIndex = 5;
                    break;
                //case DriveType.Fixed:
                //    drivenode.ImageIndex = 1;
                //    break;
                case DriveType.Removable:
                    drivenode.ImageIndex = 8;
                    break;
                //case DriveType.NoRootDirectory:

                //    drivenode.ImageIndex = 5;
                //    break;
                case DriveType.Network:
                    drivenode.ImageIndex = 6;
                    break;
                default:
                    drivenode.ImageIndex = 7;
                    break;
            }

            EnsureChildsLoaded(drivenode);
        }
    }

    private void EnsureChildsLoaded(TreeNode node)
    {
        try
        {
            FileSystemObject info = (FileSystemObject)node.Tag;
            if (info == null || info.ObjectType == FileSystemObjectType.File || info.SubNodesLoaded)
            {
                return;
            }               

            DirectoryInfo dirInfo = (DirectoryInfo)info.FileSystemInfo;
            // while (!new DriveInfo(dirInfo.Root.FullName).IsReady)
            {
                dirInfo.Refresh();
            }

            foreach (FileInfo fi in dirInfo.GetFiles())
            {
                filenode = new TreeNode(fi.Name);
                filenode.Name = fi.FullName;
                //filenode.ImageIndex = 5;
                getFileExtension(filenode.Name);
                filenode.Tag = new FileSystemObject { FileSystemInfo = fi, ObjectType = FileSystemObjectType.File };
                node.Nodes.Add(filenode);

            }

            foreach (DirectoryInfo di in dirInfo.GetDirectories())
            {
                TreeNode dirnode = new TreeNode(di.Name);
                dirnode.ImageIndex = 4;
                dirnode.Name = di.FullName;
                dirnode.Tag = new FileSystemObject { FileSystemInfo = di, ObjectType = FileSystemObjectType.Directory };
                node.Nodes.Add(dirnode);
            }

            info.SubNodesLoaded = true;
        }
        catch (Exception ex){//log it }
    }

    private void treeView1_AfterExpand(object sender, TreeViewEventArgs e)
    {
        //Load two level of nodes on demand
        FileSystemObject info = (FileSystemObject)e.Node.Tag;
        EnsureChildsLoaded(e.Node);
        foreach (TreeNode node in e.Node.Nodes)
        {
            EnsureChildsLoaded(node);
        }
    }

不需要你的 getFilesAndDir 方法。其余全部相同。随意问任何澄清。

Your getFilesAndDir method not required. rest all same. Feel free to ask any clarification.

希望这有助于。