如何检查一条路径是否是另一条路径的子路径?

时间:2011-11-11 09:16:43

标签: c# .net windows path

如何检查一条路径是否是另一条路径的子路径? 只检查子字符串不是一种方法,因为可以有诸如的项目。和..等等

8 个答案:

答案 0 :(得分:20)

不幸的是,它并不像StartsWith那么简单。

这是一个更好的答案,改编自this重复的问题。我已经使它成为一种易于使用的扩展方法。同样使用暴力catch作为访问文件系统的任何方法都可能因用户权限而失败。

public static bool IsSubDirectoryOf(this string candidate, string other)
{
    var isChild = false;
    try
    {
        var candidateInfo = new DirectoryInfo(candidate);
        var otherInfo = new DirectoryInfo(other);

        while (candidateInfo.Parent != null)
        {
            if (candidateInfo.Parent.FullName == otherInfo.FullName)
            {
                isChild = true;
                break;
            }
            else candidateInfo = candidateInfo.Parent;
        }
    }
    catch (Exception error)
    {
        var message = String.Format("Unable to check directories {0} and {1}: {2}", candidate, other, error);
        Trace.WriteLine(message);
    }

    return isChild;
}

答案 1 :(得分:5)

任何基于字符串的解决方案都可能受到directory traversal attacks或正确性问题的影响,例如尾部斜杠。不幸的是,.NET Path类不提供此功能,但Uri类以Uri.IsBaseOf()的形式提供此功能。

    Uri potentialBase = new Uri(@"c:\dir1\");

    Uri regular = new Uri(@"c:\dir1\dir2");

    Uri confusing = new Uri(@"c:\temp\..\dir1\dir2");

    Uri malicious = new Uri(@"c:\dir1\..\windows\system32\");

    Console.WriteLine(potentialBase.IsBaseOf(regular));   // True
    Console.WriteLine(potentialBase.IsBaseOf(confusing)); // True
    Console.WriteLine(potentialBase.IsBaseOf(malicious)); // False

答案 2 :(得分:0)

我发现这适用于Windows:

if (pathA.Equals(pathB, StringComparison.OrdinalIgnoreCase) ||
    pathA.StartsWith(pathB + "\\", StringComparison.OrdinalIgnoreCase))

如果您的路径中可能包含结尾字符,则可以像这样首先对其进行规范化:

pathA = Path.GetFullPath(pathA);
pathB = Path.GetFullPath(pathB);

答案 3 :(得分:0)

我使用了这样的扩展方法:

    /// <summary>
    /// Check if a directory is the base of another
    /// </summary>
    /// <param name="root">Candidate root</param>
    /// <param name="child">Child folder</param>
    public static bool IsBaseOf(this DirectoryInfo root, DirectoryInfo child)
    {
        var directoryPath = EndsWithSeparator(new Uri(child.FullName).AbsolutePath);
        var rootPath = EndsWithSeparator(new Uri(root.FullName).AbsolutePath);
        return directoryPath.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase);
    }

    private static string EndsWithSeparator(string absolutePath)
    {
        return absolutePath?.TrimEnd('/','\\') + "/";
    }

答案 4 :(得分:0)

这是我的解决方案:

// length parentDirectory <= length subDirectory
static private bool isParentDirectory(string parentDirectory, string subDirectory)
{
    if (!subDirectory.Contains(parentDirectory)) return false;

    string[] folders1 = subDirectory.Split('\\');
    string[] folders2 = parentDirectory.Split('\\');

    for (int i = 0; i < folders2.Count(); i++)
    {
        if (folders2[i] != folders1[i])
            return false;
    }
    return true;
}

答案 5 :(得分:-1)

在C#中你可以这样做:

string cp = Path.GetFullPath(childPath);
string pp = Path.GetFullPath(parentPath);

if(pp.StartsWith(cp))
    return true;
else
    return false;

答案 6 :(得分:-2)

有同样的问题。如果您将路径作为字符串

,则可以使用StartWith()
if (pathA.StartsWith (pathB + "\\")) {

虽然我不确定它是否是跨平台的,但它确实可以在PC上运行

答案 7 :(得分:-4)

这是一种方法,你有路径A和B,使用Path.GetFullPath()函数将它们转换为完整路径。接下来检查其中一个完整路径是否是另一个的起始子串。

那就是

if (Path.GetFullPath(A).StartsWith(Path.GetFullPath(B)) ||
    Path.GetFullPath(B).StartsWith(Path.GetFullPath(A)))
   { /* ... do your magic ... */ }
相关问题