Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Linq获取目录结构?_C#_.net_Linq - Fatal编程技术网

C# 使用Linq获取目录结构?

C# 使用Linq获取目录结构?,c#,.net,linq,C#,.net,Linq,我有一个应用程序,可以在其中获取计算机上的驱动器列表,当您选择一个驱动器时,我会用目录和文件填充树控件 我想尝试使用linq循环每个目录并获取其子目录 以前有人做过类似的事情吗 谢谢以下是一个如何做到这一点的示例: 这里还有一个例子:这里有一个例子说明如何做到这一点: 下面是另一个:您可以使用LINQ没有问题,尽管这是一项非常简单的任务,与文件系统相关的代码可能比与LINQ相关的代码长: private static TreeNode AddDirectory(DirectoryInfo

我有一个应用程序,可以在其中获取计算机上的驱动器列表,当您选择一个驱动器时,我会用目录和文件填充树控件

我想尝试使用linq循环每个目录并获取其子目录

以前有人做过类似的事情吗


谢谢

以下是一个如何做到这一点的示例:


这里还有一个例子:

这里有一个例子说明如何做到这一点:


下面是另一个:

您可以使用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,则允许您在从文件系统返回所有文件之前开始工作。更危险

例如: