我正在使用c#填充“文件资源管理器”解决方案。这是我的代码:
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分钟...这真的很糟糕...希望你们可以帮助有更好的解决方案或算法?那简直太好了。提前谢谢!
答案 0 :(得分:1)
加载所有目录和文件是昂贵的IO操作。在没有必要时不要加载所有东西。用户不会一直查看所有内容。
我建议你按需填充。这样的事情。
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
方法。一切都一样。随意提出任何澄清。
希望这有帮助。
答案 1 :(得分:0)
GetFiles
本质上很慢,因为您必须等待返回整个数组,然后才能与它进行交互。
如果您改为使用Directory.EnumerateFiles
,则可以在返回之前开始枚举集合(并填充树)。
http://msdn.microsoft.com/en-us/library/dd383458.aspx