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 關注
- 207 瀏覽
添加回答
舉報