如何检查目录1是否是dir2的子目录,反之亦然

什么是检查目录1是否是目录2的子目录的简单方法,反之亦然?

我检查了Path和DirectoryInfo帮助类,但没有找到系统就绪函数。 我以为它会在某处。

你们有个想法在哪里找到这个吗?

我自己试着写一张支票,但它比我开始时预期的要复杂得多。

在两种情况下使用DirectoryInfo时,可以将directory2与directory1的Parent property进行比较。

 DirectoryInfo d1 = new DirectoryInfo(@"C:\Program Files\MyApp"); DirectoryInfo d2 = new DirectoryInfo(@"C:\Program Files\MyApp\Images"); if(d2.Parent.FullName == d1.FullName) { Console.WriteLine ("Sub directory"); } 

在回答问题的第一部分时:“dir1是dir2的子目录吗?”,这段代码应该有效:

 public bool IsSubfolder(string parentPath, string childPath) { var parentUri = new Uri(parentPath); var childUri = new DirectoryInfo(childPath).Parent; while (childUri != null) { if(new Uri(childUri.FullName) == parentUri) { return true; } childUri = childUri.Parent; } return false; } 

URI (在Windows上至少在Mono / Linux上可能不同)不区分大小写。 如果区分大小写很重要,请在Uri上使用Compare方法。

这是使用Uri类更简单的方法:

 var parentUri = new Uri(parentPath); var childUri = new Uri(childPath); if (parentUri != childUri && parentUri.IsBaseOf(childUri)) { //dowork } 

请在此处查看原始答案: https : //stackoverflow.com/a/31941159/134761

  • 不区分大小写
  • 容忍\/文件夹分隔符的混合
  • 容忍..\在路径
  • 避免匹配部分文件夹名称( c:\foobar不是c:\foo的子路径)

码:

 public static class StringExtensions { ///  /// Returns true if  starts with the path . /// The comparison is case-insensitive, handles / and \ slashes as folder separators and /// only matches if the base dir folder name is matched exactly ("c:\foobar\file.txt" is not a sub path of "c:\foo"). ///  public static bool IsSubPathOf(this string path, string baseDirPath) { string normalizedPath = Path.GetFullPath(path.Replace('/', '\\') .WithEnding("\\")); string normalizedBaseDirPath = Path.GetFullPath(baseDirPath.Replace('/', '\\') .WithEnding("\\")); return normalizedPath.StartsWith(normalizedBaseDirPath, StringComparison.OrdinalIgnoreCase); } ///  /// Returns  with the minimal concatenation of  (starting from end) that /// results in satisfying .EndsWith(ending). ///  /// "hel".WithEnding("llo") returns "hello", which is the result of "hel" + "lo". public static string WithEnding([CanBeNull] this string str, string ending) { if (str == null) return ending; string result = str; // Right() is 1-indexed, so include these cases // * Append no characters // * Append up to N characters, where N is ending length for (int i = 0; i <= ending.Length; i++) { string tmp = result + ending.Right(i); if (tmp.EndsWith(ending)) return tmp; } return result; } /// Gets the rightmost  characters from a string. /// The string to retrieve the substring from. /// The number of characters to retrieve. /// The substring. public static string Right([NotNull] this string value, int length) { if (value == null) { throw new ArgumentNullException("value"); } if (length < 0) { throw new ArgumentOutOfRangeException("length", length, "Length is less than zero"); } return (length < value.Length) ? value.Substring(value.Length - length) : value; } } 

测试用例(NUnit):

 [TestFixture] public class StringExtensionsTest { [TestCase(@"c:\foo", @"c:", Result = true)] [TestCase(@"c:\foo", @"c:\", Result = true)] [TestCase(@"c:\foo", @"c:\foo", Result = true)] [TestCase(@"c:\foo", @"c:\foo\", Result = true)] [TestCase(@"c:\foo\", @"c:\foo", Result = true)] [TestCase(@"c:\foo\bar\", @"c:\foo\", Result = true)] [TestCase(@"c:\foo\bar", @"c:\foo\", Result = true)] [TestCase(@"c:\foo\a.txt", @"c:\foo", Result = true)] [TestCase(@"c:\FOO\a.txt", @"c:\foo", Result = true)] [TestCase(@"c:/foo/a.txt", @"c:\foo", Result = true)] [TestCase(@"c:\foobar", @"c:\foo", Result = false)] [TestCase(@"c:\foobar\a.txt", @"c:\foo", Result = false)] [TestCase(@"c:\foobar\a.txt", @"c:\foo\", Result = false)] [TestCase(@"c:\foo\a.txt", @"c:\foobar", Result = false)] [TestCase(@"c:\foo\a.txt", @"c:\foobar\", Result = false)] [TestCase(@"c:\foo\..\bar\baz", @"c:\foo", Result = false)] [TestCase(@"c:\foo\..\bar\baz", @"c:\bar", Result = true)] [TestCase(@"c:\foo\..\bar\baz", @"c:\barr", Result = false)] public bool IsSubPathOfTest(string path, string baseDirPath) { return path.IsSubPathOf(baseDirPath); } } 

更新2015-08-18:修复部分文件夹名称的错误匹配。 添加测试用例。

更新2016-01-29:链接到原始问题https://stackoverflow.com/a/31941159/134761

DirectoryInfo有一个属性Parent,它也是DirectoryInfo类型。 您可以使用它来确定您的目录是否是父目录的子目录。

如果第二个目录(d2)全名是d1的子文件夹,则它将包含第一个目录(d1)的全名。

这假设您使用的是有效目录

 if (d2.FullName.Contains(d1.FullName)) { //dowork } 

如果您需要检查映射驱动器,可以尝试

  static void Main(string[] args) { if (GetUNCPath(d2.FullName).ToLower().Contains(GetUNCPath(d1.FullName).ToLower())) { } } [DllImport("mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int WNetGetConnection( [MarshalAs(UnmanagedType.LPTStr)] string localName, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder remoteName, ref int length); private static string GetUNCPath(string originalPath) { StringBuilder sb = new StringBuilder(512); int size = sb.Capacity; // look for the {LETTER}: combination ... if (originalPath.Length > 2 && originalPath[1] == ':') { // don't use char.IsLetter here - as that can be misleading // the only valid drive letters are az && AZ. char c = originalPath[0]; if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { int error = WNetGetConnection(originalPath.Substring(0, 2), sb, ref size); if (error == 0) { DirectoryInfo dir = new DirectoryInfo(originalPath); string path = Path.GetFullPath(originalPath).Substring(Path.GetPathRoot(originalPath).Length); return Path.Combine(sb.ToString().TrimEnd(), path); } } } return originalPath; } 

映射驱动器的代码取自http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/6f79f2b3-d092-431f-bc28-d15d93cf5d09

如果你有两个路径,那么看看这个:

在C#中规范化目录名称

http://filedirectorypath.codeplex.com/ (我不知道它的质量)

并使用这个:

 var ancestor = new DirectoryPathAbsolute(ancestorPath); var child = new DirectoryPathAbsolute(childPath); var res = child.IsChildDirectoryOf(ancestor); //I don't think it actually checks for case-sensitive filesystems 

否则,如果您想知道目录是否作为路径中的子目录存在,请查看:

 Directory.EnumerateDirectories 

进入.Net 4.0 。 例:

path是否包含以Console开头的目录:

 //* is a wildcard. If you remove it, it search for directories called "Console" var res = Directory.EnumerateDirectories(@path, "Console*", SearchOption.AllDirectories).Any(); 

您可以使用Path.GetDirectoryName方法获取父目录。 它也适用于目录。

 public static bool IsSubfolder(DirectoryInfo parentPath, DirectoryInfo childPath) { return parentPath.FullName.StartsWith(childPath.FullName+Path.DirectorySeparatorChar); } 

这是我得到的,在第一次validation两个目录路径字符串是什么并且以路径格式我知道之后: shouldnotbechilddirpath.ToUpper().StartsWith(maybeparentdirpath.ToUpper())

如果您可能在区分大小写的文件系统中工作,请务必取出ToUppers()。