如何在C#中查找父级目录?

117

我使用这段代码来查找调试目录

public string str_directory = Environment.CurrentDirectory.ToString();

"C:\\Users\\Masoud\\Documents\\Visual Studio 2008\\Projects\\MyProj\\MyProj"

可以通过以下代码找到上级文件夹:

Path.GetDirectoryName("C:\\Users\\Masoud\\Documents\\Visual Studio 2008\\Projects\\MyProj\\MyProj\\bin\\Debug")


24
为什么人们总是在字符串上使用 ToString() 方法? - Hogan
2
@Hogan,如果属性改变了怎么办? :D - musefan
16个回答

4

由于我没有找到其他有助于以真正标准化的方式解决此问题的方法,因此这是另一个答案。

请注意,某些类似问题的答案尝试使用Uri类型,但它也无法处理尾部斜杠与没有尾部斜杠的情况。

我的另一个答案适用于将文件系统投入使用的操作,但如果我们想要立即获得已解析的路径(例如进行比较),而不通过文件系统,则C:/Temp/..C:/将被视为不同。在不经过文件系统的情况下,以这种方式导航不会向我们提供标准化的、可比较的路径。

我们该怎么办呢?

我们将基于以下发现进行构建:

Path.GetDirectoryName(path + "/") ?? ""将可靠地给出一个没有尾部斜杠的目录路径。

  • 添加斜杠(作为字符串,而不是字符)将使null路径与""相同对待。
  • GetDirectoryName将不会因为添加的斜杠而丢弃最后一个路径组件。
  • GetDirectoryName将规范化斜杠和导航点。
  • 这包括删除任何尾部斜杠。
  • 这包括通过向上导航来折叠..
  • GetDirectoryName将对空路径返回null,我们将其合并为""

我们如何使用这个?

首先,规范化输入路径

dirPath = Path.GetDirectoryName(dirPath + "/") ?? ""; // To handle nulls, we append "/" rather than '/'

然后,我们可以获取父目录,并且我们可以重复此操作任意次数以进一步向上导航:

// This is reliable if path results from this or the previous operation
path = Path.GetDirectoryName(path);

请注意,我们从未触及文件系统。如果我们使用了DirectoryInfo,则路径的任何部分都需要存在,但现在不需要存在。

3
为了避免尾随 \ 的问题,请按照以下方式调用:
  string ParentFolder =  Directory.GetParent( folder.Trim('\\')).FullName;

1
如果您只想删除尾部的 \,可以使用 TrimEnd。我不确定在其他操作系统中前导的 \ 是否重要。 - Walter Stabosz

3

在我的情况下,我正在使用.NET 6。当我使用:

public string str_directory = Environment.CurrentDirectory.ToString();

返回 C:\Projects\MyTestProject\bin\Debug\net6.0

为了到达 C:\Projects\MyTestProject,我使用以下方法:

Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent

你可以将Parent链接到Directory.GetParent(Environment.CurrentDirectory),以便到达所需的目录。 最终版本:
public string str_directory = Directory.GetParent(Environment.CurrentDirectory).Parent.Parent.ToString();

2

这是最常见的方法——它实际上取决于你具体在做什么:

(为了解释清楚,下面的示例将删除最后10个字符,这正是你要求的。但是,如果有一些业务规则驱动你需要找到特定位置,那么你应该使用这些规则来检索目录位置,而不是查找其他位置并修改它。)

// remove last 10 characters from a string
str_directory = str_directory.Substring(0,str_directory.Length-10);

1
你的第一个方法只在你确信最后的字符 恰好\bin\Debug,且没有多余的路径和拖尾的 \ 才会生效,所以它的可靠性非常脆弱。而你的第二个方法则不起作用,因为 Environment.CurrentDirectory 是一个字符串,而字符串没有 Parent 属性。 - Joe White
@Joe,我删掉了第二个。但我认为如果路径总是\bin\debug,这是一个有效的答案。正如我所说,OP应该真正看看驱动需要目录的BR,并使用不同的方法(我可能会使用配置项,但我猜测BR和程序结构)。 - Hogan
虽然不是完美的,且易碎,但这是我找到的唯一解决方案。建议修改: "str_directory.length" 应该改为 "str_directory.Length",小写字母 L 是不可接受的。 - OverMars

2
尝试以下方法获取您的解决方案:

string directory = System.IO.Directory.GetParent(System.IO.Directory.GetParent(Environment.CurrentDirectory).ToString()).ToString();

1

你不应该尝试这样做。Environment.CurrentDirectory 可以获取可执行文件目录的路径。这是独立于 .exe 文件位置的一致性路径。您不应尝试访问假定在相对位置的文件。

我建议您将要访问的任何资源移动到本地位置,或者系统目录(例如AppData)中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接