How to check if one path is a child of another path?

前端 未结 7 1417
温柔的废话
温柔的废话 2020-12-09 17:57

How to check if one path is a child of another path?
Just checking for substring is not a way to go, because there can items such as . and .., etc

相关标签:
7条回答
  • 2020-12-09 18:28

    Unfortunately it's not as simple as StartsWith.

    Here's a better answer, adapted from this duplicate question. I've made it an extension method for ease of use. Also using a brute-force catch as just about any method that accesses the file system can fail based on user permissions.

    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;
    }
    
    0 讨论(0)
  • 2020-12-09 18:29

    Any string-based solution is potentially subject to directory traversal attacks or correctness issues with things like trailing slashes. Unfortunately, the .NET Path class does not provide this functionality, however the Uri class does, in the form of 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
    
    0 讨论(0)
  • 2020-12-09 18:33

    Had the same issue. You can use StartWith() if you have the path as string

    if (pathA.StartsWith (pathB + "\\")) {
    

    Though I am not sure if it is cross platform or not, but it does work on PC

    0 讨论(0)
  • 2020-12-09 18:38

    In C# you can do it like this:

    string cp = Path.GetFullPath(childPath);
    string pp = Path.GetFullPath(parentPath);
    
    if(pp.StartsWith(cp))
        return true;
    else
        return false;
    
    0 讨论(0)
  • 2020-12-09 18:38

    I have found that this works for windows:

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

    If your paths might have trailing characters, you could normalize them like this first:

    pathA = Path.GetFullPath(pathA);
    pathB = Path.GetFullPath(pathB);
    
    0 讨论(0)
  • 2020-12-09 18:41

    This would be one way to go, you have path A and B, convert them to full paths with the Path.GetFullPath() function. Next check if one of the full paths is a starting substring of the other.

    So that would be

    if (Path.GetFullPath(A).StartsWith(Path.GetFullPath(B)) ||
        Path.GetFullPath(B).StartsWith(Path.GetFullPath(A)))
       { /* ... do your magic ... */ }
    
    0 讨论(0)
提交回复
热议问题