如何在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个回答

161

27
如果目录名以斜杠结尾,你需要调用GetParent两次。 - northben
4
这似乎适用于相对路径(令人惊喜),但随后没有办法让您将结果返回(令人不满意)。 - Adam
21
您可以通过使用DirectoryInfo.Parent来避免尾部斜杠的问题,例如:new System.IO.DirectoryInfo("c:/path/to/somewhere//").Parent。@northben - mcNux
Directory.GetParent(path.TrimEnd(Path.DirectorySeparatorChar)).FullName - Paul Williams

55
string parent = System.IO.Directory.GetParent(str_directory).FullName;

请参阅BOL


48
如果你在现有路径结尾加上..\..,操作系统将会正确地浏览到父文件夹的上一级目录。这应该可以解决问题:
System.IO.Path.Combine("C:\\Users\\Masoud\\Documents\\Visual Studio 2008\\Projects\\MyProj\\MyProj\\bin\\Debug", @"..\..");
如果您浏览该路径,则将浏览到祖父目录。

我需要的正是这个。 - Muzaffer Galata
8
使用 "Path.Combine" 的结果可以通过 "Path.GetFullPath" 进行清理,以获得 "C:\Users\Masoud\Documents\Visual Studio 2008\Projects\MyProj\MyProj" 的路径。 - Konstantin
1
这是在目录树中向上跳转多个级别的最佳方法。 - Trung Le
1
如果您想获取文件的“父”目录,则此方法无法实现。(我知道这不是帖子作者想要的,但这正是我来到这里的原因。) - supergra
1
当然不是。但是你可以随意使用 System.IO.Path.GetDirectoryName 来获取文件的目录。 - Pierre-Alain Vigeant

26
编辑:下面的答案中提到的规范化仅在使用路径访问文件系统时发生,而不是在字符串本身上。相比之下,答案here纯粹使用路径字符串实现了结果和规范化,而根本不使用文件系统。

我发现System.IO.Path.Combine(myPath, "..")的变体是最简单和最可靠的。如果northben所说的是真的,那么GetParent如果有尾部斜杠,则需要额外调用。对我来说,这是不可靠的。

Path.Combine确保您在斜杠上永远不会出错。

..在Windows中的行为与其他地方完全相同。您可以在cmd或资源管理器中的路径中添加任意数量的\..,它将完全按照我下面描述的方式运行。

一些基本的..行为:

  1. 如果有文件名,..将删除它:

Path.Combine(@"D:\Grandparent\Parent\Child.txt", "..") => D:\Grandparent\Parent\

  1. If the path is a directory, .. will move up a level:

Path.Combine(@"D:\Grandparent\Parent\", "..") => D:\Grandparent\

  1. ..\.. follows the same rules, twice in a row:

Path.Combine(@"D:\Grandparent\Parent\Child.txt", @"..\..") => D:\Grandparent\ Path.Combine(@"D:\Grandparent\Parent\", @"..\..") => D:\

  1. And this has the exact same effect:

Path.Combine(@"D:\Grandparent\Parent\Child.txt", "..", "..") => D:\Grandparent\ Path.Combine(@"D:\Grandparent\Parent\", "..", "..") => D:\


1
我同意这种方法的优点是无论路径是否有尾部反斜杠都能正常工作。而且在需要一个不带点的简单路径的情况下,你可以对结果应用 Path.GetFullPath(() 方法。 - RenniePet
2
两年后,我又回到了这里。请注意,Path.GetFullPath(()通常返回没有尾部反斜杠的路径,但是当你到达根目录时,例如“E:\”,那么就会有一个反斜杠。 - RenniePet
2
无论是.NET 4.7还是.NET Core 2.1,这都不起作用:Path.Combine(@"D:\Grandparent\Parent\Child.txt", @"..") = D:\Grandparent\Parent\Child.txt\.. - Métoule
为了解决路径问题,您可以这样做: FileInfo f = new FileInfo(Path.GetDirectoryName(Path.Combine("C:\Users\Masoud\Documents\Visual Studio 2008\Projects\MyProj\MyProj\bin\Debug\", @"....", "test.txt"))); f.DirectoryName; - abdkok
@SalientBrain 这个已经讨论过了。请看我对 @Métoule 的回复。简而言之,Path.Combine 不会截断字符串本身。相反,一旦用于访问文件系统的路径就会产生预期的效果。参见这个答案以获取一个非延迟的替代方案(同样也不依赖于文件系统来构建路径)。 - Timo
显示剩余3条评论

12

Directory.GetParent可能是更好的答案,但为了完整起见,还有一种接受字符串并返回字符串的不同方法:Path.GetDirectoryName

string parent = System.IO.Path.GetDirectoryName(str_directory);

1
请注意,Path.GetDirectoryName在处理相对路径时效果不佳,而Directory.GetParent则可以。 - nawfal
3
冒着重复别人已经提到的风险 - 请记住,Directory.GetParent()实际上访问文件系统,而Path.GetDirectoryName()只是字符串操作。 - Dave

11
要获取“祖父”目录,请调用Directory.GetParent()两次:
var gparent = Directory.GetParent(Directory.GetParent(str_directory).ToString());

1
var gparent = Directory.GetParent(str_directory).Parent; // Cleaner? - JohnB

6

像这样:

System.IO.DirectoryInfo myDirectory = new DirectoryInfo(Environment.CurrentDirectory);
string parentDirectory = myDirectory.Parent.FullName;

祝你好运!


1
myDirectory.Parent.ToString() 返回子文件夹的名称,而不是完整路径,正是我想要的。此外,不必像上面显示的那样执行 Directory.GetParent(Directory.GetParent(str_directory).ToString()); ,只需要使用 myDirectory.parent.parent.ToString() 就可以获取“祖父母”文件夹。 - Weihui Guo
1
我认为这种方法是最好的,因为它处理了目录路径末尾带斜杠的情况。而如果你使用Directory.GetParent(),你必须调用两次才能去掉斜杠并获取实际的父级目录。 - Magnus

6
没有人提供能够在各种表单中共用的解决方案。我知道这并不是特别被问到的问题,但我正在Linux环境下工作,大多数解决方案(截至我发布此帖时)都会出现错误。
硬编码路径分隔符(以及其他内容)只会在Windows系统之外的任何地方产生错误。
在我的原始解决方案中,我使用了:
char filesep = Path.DirectorySeparatorChar;
string datapath = $"..{filesep}..{filesep}";

然而,在看到这里的一些答案后,我进行了调整:

string datapath = Directory.GetParent(Directory.GetParent(Directory.GetCurrentDirectory()).FullName).FullName; 

5

4
IO.Path.GetFullPath(@"..\..")

如果你在项目属性中的“生成”选项卡下的“输出路径”中清空了“bin\Debug\”,那么你可以直接使用AppDomain.CurrentDomain.BaseDirectory

这适用于当前的.NET版本,目前为5。干杯! - Ali

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