为了账号安全,请及时绑定邮箱和手机立即绑定

从 DirectoryInfo 中搜索父目录

从 DirectoryInfo 中搜索父目录

C#
慕桂英3389331 2022-10-23 16:43:59
有没有办法搜索特定的父目录?我知道我可以使用这个获取目录的父级Directory.GetParent(Directory.GetCurrentDirectory()).FullName但这会返回直接父级,有什么方法可以在路径的目录层次结构中搜索特定的父级?编辑我想要实现的是,如果我有这样的当前目录C:/Project/Source/Dev/Database所以我想访问Source 我知道我可以通过GetParent两次调用方法来访问它的目录,但我认为这不是正确的方法,因为如果将来我的文件当前目录发生变化并且它会进一步下降怎么办。Source所以我想要一些完整的证明方式,无论我在当前目录中有多深,我都可以直接找到目录的路径,因为那肯定我会在目录中Source所以像FindParent('Source')
查看完整描述

4 回答

?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

您可以尝试这样的事情(for循环):


private static IEnumerable<String> ParentDirectories(string directory = null) {

  for (string dir = null == directory ? Directory.GetCurrentDirectory() : directory;

       dir != null;

       dir = Directory.GetParent(dir)?.FullName)

    yield return dir;

}

演示:


var demo = string.Join(Environment.NewLine, 

  ParentDirectories(@"C:/Project/Source/Dev/Database"));


Console.Write(demo);

结果:


C:/Project/Source/Dev/Database // initial directory

C:\Project\Source\Dev          // and its all parents

C:\Project\Source

C:\Project

C:\

如果您不想包含目录本身,请添加.Skip(1):


var demo = string.Join(Environment.NewLine, 

  ParentDirectories(@"C:/Project/Source/Dev/Database").Skip(1));

最后,如果你想找到一个以 结尾的父目录Source:


string dirName = "Source";


string myParent = ParentDirectories(@"C:/Project/Source/Dev/Database")

  .FirstOrDefault(dir => string.Equals(

     dirName,

     new DirectoryInfo(dir).Name, 

     StringComparison.OrdinalIgnoreCase));


Console.Write(myParent); 

结果:


C:\Project\Source


查看完整回答
反对 回复 2022-10-23
?
梦里花落0921

TA贡献1772条经验 获得超6个赞

Directory.GetCurrentDirectory()返回一个字符串,表示当前目录的完整绝对路径。


如果要获取特定父目录的路径,可以简单地使用substring:


var path = Directory.GetCurrentDirectory(); // Suppose C:/Project/Source/Dev/Database

var sourceDir = new string[] {Path.DirectorySeparatorChar + "Source" + Path.DirectorySeparatorChar,

                           Path.AltDirectorySeparatorChar + "Source" + Path.AltDirectorySeparatorChar};


var sourcePath = path.IndexOf(sourceDir[0], StringComparison.OrdinalIgnoreCase) > -1 ?

    path.Substring(0, path.IndexOf(sourceDir[0]) + sourceDir[0].Length) :

    path.IndexOf(sourceDir[1], StringComparison.OrdinalIgnoreCase) > -1 ? 

        path.Substring(0, path.IndexOf(sourceDir[1]) + sourceDir[1].Length) : 

        null;

我使用Path.DirectorySeparatorCharandPath.AltDirectorySeparatorChar作为分隔符,以便代码在每个平台上都可以正常工作。


查看完整回答
反对 回复 2022-10-23
?
慕沐林林

TA贡献2016条经验 获得超9个赞

在遍历任何类型的序列(数字序列、目录序列、图中的节点序列)时,您可以选择使用递归。


目录结构(当忽略任何类型的链接时)是称为有向无环图(或 DAG)的数据结构的子集——这个子集通常不会重新加入并且永远扇出(只要操作系统允许给定嵌套目录的深度)。我们通常将其称为树结构。


从这个角度来看,递归表面的概念对大多数人来说可能并不奇怪,因为程序员应用递归来遍历树是很常见的。但是,无论您是向上还是向下遍历树只是一个实现细节。


没有理由不能使用递归来遍历树。


这是一个简单的控制台应用程序(使用 .net6 约定和 C#10 语法编写),您可以学习它,然后也许可以应用它来解决未来的问题。


using System.Runtime.InteropServices; // For the [Optional] attribute


var dir = Directory.GetCurrentDirectory();

var file = Directory.GetFiles(dir).First();

var projFile = DirectoryRecursor.RecurseUpwardsUntilFileIsFoundWith(".csproj", file, 5);

Console.WriteLine(projFile);



public static class DirectoryRecursor

{

    public static FileInfo? RecurseUpwardsUntilFileIsFoundWith(

        string stringToMatch,

        string sourceFile,

        [Optional] int? maxParentDirLevel)

    {

        if (maxParentDirLevel is not null && maxParentDirLevel == 0) return null; // try and stave off disaster


        var dirName = Path.GetDirectoryName(sourceFile);

        if (dirName is null) return null;


        var csprojFile = Directory.GetFiles(dirName).Where(x => x.EndsWith(stringToMatch)).SingleOrDefault();

        if (csprojFile is null)

        {

            if (ThereIsAParentDirectory(new DirectoryInfo(sourceFile), out var parentDir))

            {

                return RecurseUpwardsUntilFileIsFoundWith(stringToMatch, parentDir.FullName, maxParentDirLevel - 1);

            }

            else

            {

                return null;

            }

        }


        return new FileInfo(csprojFile);

    }


    public static bool ThereIsAParentDirectory(DirectoryInfo dir, out DirectoryInfo parentDir)

    {

        if (dir.Parent is not null)

        {

            parentDir = dir.Parent;

            return dir.Parent.Exists;

        }


        parentDir = dir;

        return false;

    }

}

一个快速的旁注:


在树上和下应用递归的一个例子(我承认它目前不是开源的),是www.palavyr.com上的对话构建器。这个对话树被实现为一个双链表,以促进对话树上下的递归。我正计划制作一篇技术博客文章来解释这个实现——一旦我完成了它,我会用它来更新这个响应。


查看完整回答
反对 回复 2022-10-23
?
HUX布斯

TA贡献1876条经验 获得超6个赞

实际上,我认为已经存在一种方式或功能,但是如果我必须自己编写,那么我编写的这个解决方案对我有用


    private static string GetParent(string directoryPath, string parent)

    {

        DirectoryInfo directory = new DirectoryInfo(directoryPath);

        while (directory.Parent!=null)

        {

            if (directory.Parent.Name.ToLower() == parent.ToLower())

            {

                return directory.Parent.FullName;

            }


            directory = directory.Parent;

        }


        return null;

    }


查看完整回答
反对 回复 2022-10-23
  • 4 回答
  • 0 关注
  • 173 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信