如何在C#中找到父目录?


85

我使用此代码查找调试目录

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

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

如何找到如下所示的父文件夹?

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


15
人们为什么总是在字符串上使用ToString()?
霍根

1
@Hogan,如果属性发生变化?:D
musefan 2011年

Answers:


126

您可以System.IO.Directory.GetParent()用来检索给定目录的父目录。


21
如果目录末尾有斜杠,则必须两次调用GetParent
northben

2
这似乎可以在相对路径上工作(惊喜),但是却没有办法使结果恢复(惊喜)。
亚当

14
您可以改用来避免出现斜线问题DirectoryInfo.Parent。例如new System.IO.DirectoryInfo("c:/path/to/somewhere//").Parent。@northben
mcNux

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

BOL


35

如果添加..\..到现有路径,则操作系统将正确浏览grand-parent文件夹。

那应该做的工作:

System.IO.Path.Combine("C:\\Users\\Masoud\\Documents\\Visual Studio 2008\\Projects\\MyProj\\MyProj\\bin\\Debug", @"..\..");

如果浏览该路径,则将浏览祖父母目录。


1
看起来不错,但不幸的是给了C:\ Users \ Masoud \ Documents \ Visual Studio 2008 \ Projects \ MyProj \ MyProj \ bin \ Debug \ .. \ ..
StuartQ 2014年

是的,如果您浏览该路径,则将浏览父-父目录。
Pierre-Alain Vigeant 2014年

公平的观点,尽管我必须在您的评论中进行修改才能将观点归还给我,但我将删除不赞成投票的人。
StuartQ 2014年

3
可以通过“ Path.GetFullPath”传递“ Path.Combine”的结果以进行清理。那就是去“ C:\ Users \ Masoud \ Documents \ Visual Studio 2008 \ Projects \ MyProj \ MyProj”
Konstantin

1
这是在目录树中上几个级别的最佳方法
Trung Le

18

我发现的变体System.IO.Path.Combine(myPath, "..")是最简单,最可靠的。更重要的是,如果northben所说的是正确的,那么如果出现斜杠,则GetParent需要额外的调用。对我来说,那是不可靠的。

Path.Combine确保使用斜线永远不会出错。

..行为与Windows中的其他任何地方一样。您可以\..在cmd或资源管理器中的路径中添加任意数量的,并且其行为将与我在下面描述的完全一样。

一些基本..行为:

  1. 如果有文件名,..则将其砍掉:

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

  1. 如果路径是目录,..将向上移动一个级别:

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

  1. ..\.. 遵循相同的规则,连续两次:

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

  1. 这具有完全相同的效果:

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


1
我同意,此方法的优点是不管路径是否带有反斜杠都有效。而且,在您需要一条没有点的简单路径的情况下,可以将Path.GetFullPath(()应用于结果
。– RenniePet 2016年

1
两年后,我又回到了这里。请注意,Path.GetFullPath(()通常返回没有任何反斜杠的路径,但是当您进入根目录(例如“ E:\”)时,会出现一个反斜杠
。– RenniePet

这不工作,也没有用.NET 4.7,也没有.NET 2.1的核心:Path.Combine(@"D:\Grandparent\Parent\Child.txt", @"..")=D:\Grandparent\Parent\Child.txt\..
Métoule

至少在MacOS上通过Unity,这不会为我截断文件名。
supergra

@Métoule@supergra我看到了困惑。Path.Combine不会截断字符串本身。该路径(曾经用于访问文件系统)具有预期的作用。但是,我同意这不是最理想的。请参阅此页面上的最新答案,以获取一种修改字符串而不需要文件系统解析路径的方法。
蒂莫


8

Directory.GetParent可能是一个更好的答案,但对于完整性有不同的方法,它采用字符串并返回字符串:Path.GetDirectoryName

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

1
请注意,Path.GetDirectoryName不能与相对路径一起使用。Directory.GetParent可以。
nawfal

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()即可获得“祖父母”。
郭卫辉

1
我发现此方法是最好的,因为它可以处理目录路径中带有尾部斜杠的情况。而如果使用Directory.GetParent(),则必须调用两次以删除斜杠,然后获取实际的父级。
Magnus


3

为避免尾随\出现问题,请按以下方式调用:

  string ParentFolder =  Directory.GetParent( folder.Trim('\\')).FullName;

1
TrimEnd如果只想删除尾随`'s . I'm not sure if a leading `在其他操作系统中很重要,则可以使用。
Walter Stabosz

2

要获得您的解决方案,请尝试此

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

2

这是最常见的方式-实际上取决于您在做什么:(为说明起见,下面的示例将删除您所要求的最后10个字符,但是是否有某些业务规则正在推动您的需求要查找特定位置,您应该使用这些位置来检索目录位置,而不是查找其他位置并进行修改。)

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

仅当您知道最后一个字符完全是 \bin\Debug,没有尾随` and no other path, so it's extraordinarily fragile. Your second doesn't work because Environment.CurrentDirectory是字符串,并且字符串没有Parent属性时,才可以使用第一个字符。
乔·怀特

@Joe,我删除了第二个。但是我认为这是一个有效的答案,如果该路径始终为\ bin \ debug,那么它将起作用。正如我所说的OP真的应该看哪个BR是驱动该目录的需要,使用不同的方法(我可能会使用一个配置项,但我在BR和程序结构猜测。)
霍根

虽然不是完美且脆弱,但这是唯一对我有用的解决方案。建议的编辑:“ str_directory.length”应为“ str_directory.Length”,小写L不能接受。
OverMars

2

没有人提供过可以跨表格工作的解决方案。我知道并没有特别要求,但是我正在linux环境中工作,在该环境中,大多数解决方案(如我发布本文时)都会提供错误。

硬编码路径分隔符(以及其他内容)将在Windows系统之外的任何情况下产生错误。

在我最初的解决方案中,我使用了:

char filesep = Path.DirectorySeparatorChar;
string datapath = $"..{filesep}..{filesep}";

但是,在这里看到一些答案后,我将其调整为:

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

2

由于我发现的其他任何方法都无法以一种真正的标准化方式解决此问题,因此这是另一个答案。

请注意,对类似问题的一些答案尝试使用该Uri类型,但是在结尾斜杠与没有结尾斜杠之间都比较困难。

我在此页面上的其他答案适用于使文件系统正常工作的操作,但是如果我们现在想拥有已解析的路径(例如出于比较的原因),而无需遍历文件系统,C:/Temp/..并且C:/将被视为不同。如果不遍历文件系统,以这种方式导航不会为我们提供标准化的,可比较的路径。

我们能做些什么?

我们将基于以下发现:

Path.GetDirectoryName(path + "/") ?? ""可靠地为我们提供目录路径,且不带斜杠

  • 添加斜杠(按string而不char)将对null路径进行处理""
  • GetDirectoryName 由于增加了斜杠,将避免丢弃最后的路径组件。
  • GetDirectoryName 将规范斜线和导航点。
  • 这包括删除任何尾部斜杠。
  • 这包括..通过向上导航而折叠。
  • GetDirectoryName将返回null一条空路径,我们将合并为""

我们如何使用这个?

首先,标准化输入路径

dirPath = Path.GetDirectoryName(dirPath + "/") ?? "";

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

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

请注意,我们从未接触过文件系统。就像我们曾经使用过的那样,路径的任何部分都不需要存在DirectoryInfo


1

您不应该尝试这样做。Environment.CurrentDirectory为您提供可执行目录的路径。不管.exe文件在哪里,这都是一致的。您不应尝试访问假定位于向后相对位置的文件

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


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

如果清除bin\Debug\项目属性->生成->输出路径中的“”,则可以使用AppDomain.CurrentDomain.BaseDirectory

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.