检查目录1是否是目录2的子目录是一种简单的方法,反之亦然?
我检查了Path和DirectoryInfo帮助类,但没有发现系统就绪函数。我以为它会在某处。
你们有个想法在哪里找到这个吗?
我自己试着写一张支票,但这比我开始时的预期要复杂得多。
答案 0 :(得分:10)
在回答问题的第一部分时:“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上可能不同)不区分大小写。如果区分大小写很重要,请改用Compare
上的Uri
方法。
答案 1 :(得分:7)
使用Uri类这是一种更简单的方法:
var parentUri = new Uri(parentPath);
var childUri = new Uri(childPath);
if (parentUri != childUri && parentUri.IsBaseOf(childUri))
{
//dowork
}
答案 2 :(得分:3)
请在此处查看原始答案:https://stackoverflow.com/a/31941159/134761
\
和/
文件夹分隔符的混合..\
c:\foobar
而不是c:\foo
的子路径代码:
public static class StringExtensions
{
/// <summary>
/// Returns true if <paramref name="path"/> starts with the path <paramref name="baseDirPath"/>.
/// 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").
/// </summary>
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);
}
/// <summary>
/// Returns <paramref name="str"/> with the minimal concatenation of <paramref name="ending"/> (starting from end) that
/// results in satisfying .EndsWith(ending).
/// </summary>
/// <example>"hel".WithEnding("llo") returns "hello", which is the result of "hel" + "lo".</example>
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;
}
/// <summary>Gets the rightmost <paramref name="length" /> characters from a string.</summary>
/// <param name="value">The string to retrieve the substring from.</param>
/// <param name="length">The number of characters to retrieve.</param>
/// <returns>The substring.</returns>
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
答案 3 :(得分:1)
如果你有两条路,请看看:
Normalize directory names in 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();
答案 4 :(得分:1)
DirectoryInfo有一个属性Parent,它也是一个DirectoryInfo类型。您可以使用它来确定您的目录是否是父目录的子目录。
答案 5 :(得分:1)
第二个目录(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 a-z && A-Z.
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
获取的映射驱动器代码答案 6 :(得分:0)
您可以使用Path.GetDirectoryName Method 获取父目录。它也适用于目录。
答案 7 :(得分:0)
public static bool IsSubfolder(DirectoryInfo parentPath, DirectoryInfo childPath)
{
return parentPath.FullName.StartsWith(childPath.FullName+Path.DirectorySeparatorChar);
}
答案 8 :(得分:0)
在angularsen's answer中编写的出色测试案例的帮助下,我在用于Windows的.NET Core 3.1上编写了以下更简单的扩展方法:
public static bool IsSubPathOf(this string dirPath, string baseDirPath)
{
dirPath = dirPath.Replace('/', '\\');
if (!dirPath.EndsWith('\\'))
{
dirPath += '\\';
}
baseDirPath = baseDirPath.Replace('/', '\\');
if (!baseDirPath.EndsWith('\\'))
{
baseDirPath += '\\';
}
var dirPathUri = new Uri(dirPath).LocalPath;
var baseDirUri = new Uri(baseDirPath).LocalPath;
return dirPathUri.Contains(baseDirUri, StringComparison.OrdinalIgnoreCase);
}
答案 9 :(得分:-1)
这是我得到的,在首先验证两个目录路径字符串是什么并且以路径格式我知道之后:shouldnotbechilddirpath.ToUpper().StartsWith(maybeparentdirpath.ToUpper())
如果您可能在区分大小写的文件系统中工作,请务必取出ToUppers()。
答案 10 :(得分:-10)
在两种情况下使用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");
}