C# 使用Linq获取目录结构?
我有一个应用程序,可以在其中获取计算机上的驱动器列表,当您选择一个驱动器时,我会用目录和文件填充树控件 我想尝试使用linq循环每个目录并获取其子目录 以前有人做过类似的事情吗C# 使用Linq获取目录结构?,c#,.net,linq,C#,.net,Linq,我有一个应用程序,可以在其中获取计算机上的驱动器列表,当您选择一个驱动器时,我会用目录和文件填充树控件 我想尝试使用linq循环每个目录并获取其子目录 以前有人做过类似的事情吗 谢谢以下是一个如何做到这一点的示例: 这里还有一个例子:这里有一个例子说明如何做到这一点: 下面是另一个:您可以使用LINQ没有问题,尽管这是一项非常简单的任务,与文件系统相关的代码可能比与LINQ相关的代码长: private static TreeNode AddDirectory(DirectoryInfo
谢谢以下是一个如何做到这一点的示例:
这里还有一个例子:这里有一个例子说明如何做到这一点:
下面是另一个:您可以使用LINQ没有问题,尽管这是一项非常简单的任务,与文件系统相关的代码可能比与LINQ相关的代码长:
private static TreeNode AddDirectory(DirectoryInfo directory)
{
DirectoryInfo[] subdirs = directory.GetDirectories();
FileInfo[] files = directory.GetFiles();
IEnumerable<TreeNode> subdirNodes = from subdir in subdirs select AddDirectory(subdir);
IEnumerable<TreeNode> fileNodes = from file in files select new TreeNode(file.Name);
return new TreeNode(
directory.Name,
subdirNodes.Concat(fileNodes).ToArray());
}
private静态树节点AddDirectory(DirectoryInfo目录)
{
DirectoryInfo[]subdirs=directory.GetDirectories();
FileInfo[]files=目录.GetFiles();
IEnumerable subdirNodes=从subdir中的subdir选择AddDirectory(subdir);
IEnumerable fileNodes=从文件中的文件选择新树节点(file.Name);
返回新树节点(
目录名,
Concat(fileNodes.ToArray());
}
虽然文件系统相关代码可能比LINQ相关代码长,但使用LINQ没有问题:
private static TreeNode AddDirectory(DirectoryInfo directory)
{
DirectoryInfo[] subdirs = directory.GetDirectories();
FileInfo[] files = directory.GetFiles();
IEnumerable<TreeNode> subdirNodes = from subdir in subdirs select AddDirectory(subdir);
IEnumerable<TreeNode> fileNodes = from file in files select new TreeNode(file.Name);
return new TreeNode(
directory.Name,
subdirNodes.Concat(fileNodes).ToArray());
}
private静态树节点AddDirectory(DirectoryInfo目录)
{
DirectoryInfo[]subdirs=directory.GetDirectories();
FileInfo[]files=目录.GetFiles();
IEnumerable subdirNodes=从subdir中的subdir选择AddDirectory(subdir);
IEnumerable fileNodes=从文件中的文件选择新树节点(file.Name);
返回新树节点(
目录名,
Concat(fileNodes.ToArray());
}
作为旁白-您可能有兴趣知道.NET 4.0正在内置LINQ enable文件操作(显然是适当的惰性操作-而不是在数组上迭代)。请在此条目上查找“文件系统枚举改进”。作为旁白-您可能有兴趣知道.NET 4.0正在内置启用LINQ的文件操作(显然是适当的惰性操作-而不是在数组上迭代)。查看此条目上的“文件系统枚举改进”。通常,当UI显示文件和文件夹树时,它不会在一次扫描中扫描整个层次结构。相反,它只为展开的节点收集足够的信息。然后,当用户展开一个节点时,它会努力找出需要放置在该节点下的内容
原因很简单,因为许多人的系统驱动器上的文件和目录数量可能会非常大,因此如果他们要求查看驱动器C:的根目录,您的应用程序将冻结一段时间
根据您使用的是WPF还是Windows窗体,情况略有不同。在WPF中,展开的事件位于树视图项
本身,而在Windows窗体中,在树视图
上有几个展开事件(在树节点
上没有事件)。但模式基本相同
添加表示文件夹的树节点时,请在其下创建虚拟节点。给它一些特殊标识(标记属性中的特殊标志,或者可能是包含无效文件系统字符的唯一名称)。这将允许用户扩展该节点。然后在扩展事件处理程序中,查看第一个子节点-如果它是特殊的虚拟节点,请删除它,然后为该节点创建真正的子节点集。这将确保每个目录只收集一次实际节点
下面是WPF的一个大致想法:
TreeViewItem folderNode = new TreeViewItem { Header = Path.GetFileName(folderPath) };
parentNode.Items.Add(folderNode);
// create the dummy item under it
TreeViewItem dummy = new TreeViewItem { Tag = _dummyTag };
folderNode.Items.Add(dummy);
folderNode.Expanded += delegate
{
if (folderNode.Items.Count == 1)
{
if (((TreeViewItem)folderNode.Items[0]).Tag == _dummyTag)
{
folderNode.Items.Clear();
CreateFolderChildren(folderNode, folderPath);
}
}
};
_dummyTag只能是一个字段:
private static readonly object _dummyTag = new object();
通常,当UI显示文件和文件夹树时,它不会在一次快照中扫描整个层次结构。相反,它只为展开的节点收集足够的信息。然后,当用户展开一个节点时,它会努力找出需要放置在该节点下的内容 原因很简单,因为许多人的系统驱动器上的文件和目录数量可能会非常大,因此如果他们要求查看驱动器C:的根目录,您的应用程序将冻结一段时间 根据您使用的是WPF还是Windows窗体,情况略有不同。在WPF中,展开的事件位于
树视图项
本身,而在Windows窗体中,在树视图
上有几个展开事件(在树节点
上没有事件)。但模式基本相同
添加表示文件夹的树节点时,请在其下创建虚拟节点。给它一些特殊标识(标记属性中的特殊标志,或者可能是包含无效文件系统字符的唯一名称)。这将允许用户扩展该节点。然后在扩展事件处理程序中,查看第一个子节点-如果它是特殊的虚拟节点,请删除它,然后为该节点创建真正的子节点集。这将确保每个目录只收集一次实际节点
以下是WPF的大致概念:
TreeViewItem folderNode = new TreeViewItem { Header = Path.GetFileName(folderPath) };
parentNode.Items.Add(folderNode);
// create the dummy item under it
TreeViewItem dummy = new TreeViewItem { Tag = _dummyTag };
folderNode.Items.Add(dummy);
folderNode.Expanded += delegate
{
if (folderNode.Items.Count == 1)
{
if (((TreeViewItem)folderNode.Items[0]).Tag == _dummyTag)
{
folderNode.Items.Clear();
CreateFolderChildren(folderNode, folderPath);
}
}
};
_dummyTag只能是一个字段:
private static readonly object _dummyTag = new object();
让我再次拉皮条吧:)
样本:
var di = new DirectoryInfo("foo");
var q = di.TraverseDepthFirst( x => x.GetFiles(), x => x.GetDirectories());
var nq = from fs in q
from f in fs
select f;
foreach (FileInfo dirfiles in nq)
{
...
}
让我再次拉皮条吧:)
样本:
var di = new DirectoryInfo("foo");
var q = di.TraverseDepthFirst( x => x.GetFiles(), x => x.GetDirectories());
var nq = from fs in q
from f in fs
select f;
foreach (FileInfo dirfiles in nq)
{
...
}
如果使用GetFiles,将启动一个阻塞操作,该操作将返回一个数组。如果改为使用you get lazy evaluation,则允许您在从文件系统返回所有文件之前开始工作。更危险 例如:
如果使用GetFiles,将启动一个阻塞操作,该操作将返回一个数组。如果改为使用you get lazy evaluation,则允许您在从文件系统返回所有文件之前开始工作。更危险 例如: