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
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作为分隔符,以便代码在每个平台上都可以正常工作。
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上的对话构建器。这个对话树被实现为一个双链表,以促进对话树上下的递归。我正计划制作一篇技术博客文章来解释这个实现——一旦我完成了它,我会用它来更新这个响应。
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;
}
- 4 回答
- 0 关注
- 173 浏览
添加回答
举报