Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何检查一条路径是否是另一条路径的子路径?_C#_.net_Windows_Path - Fatal编程技术网

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

C# 如何检查一条路径是否是另一条路径的子路径?,c#,.net,windows,path,C#,.net,Windows,Path,如何检查一条路径是否是另一条路径的子路径? 仅仅检查子字符串并不是一种可行的方法,因为可能会出现诸如。还有..等等这是一种方法,您有路径A和B,使用path.GetFullPath()函数将它们转换为完整路径。下一步检查完整路径之一是否是另一个路径的起始子字符串 那就是 if (Path.GetFullPath(A).StartsWith(Path.GetFullPath(B)) || Path.GetFullPath(B).StartsWith(Path.GetFullPath(A))

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

仅仅检查子字符串并不是一种可行的方法,因为可能会出现诸如。还有..等等

这是一种方法,您有路径A和B,使用path.GetFullPath()函数将它们转换为完整路径。下一步检查完整路径之一是否是另一个路径的起始子字符串

那就是

if (Path.GetFullPath(A).StartsWith(Path.GetFullPath(B)) ||
    Path.GetFullPath(B).StartsWith(Path.GetFullPath(A)))
   { /* ... do your magic ... */ }
在C#中,您可以这样做:

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

if(pp.StartsWith(cp))
    return true;
else
    return false;
    /// <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('/','\\') + "/";
    }

不幸的是,它不像
StartsWith
那样简单

这里有一个更好的答案,改编自重复的问题。为了便于使用,我将其作为一种扩展方法。同样,使用蛮力捕获文件系统,因为几乎任何访问文件系统的方法都可能因用户权限而失败

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;
}

有同样的问题。如果路径为字符串,则可以使用
StartWith()

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

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

任何基于字符串的解决方案都可能会遇到诸如尾部斜杠之类的错误或正确性问题。不幸的是,.NET
Path
类不提供此功能,而
Uri
类以
Uri.IsBaseOf()的形式提供此功能


我发现这适用于windows:

if (pathA.Equals(pathB, StringComparison.OrdinalIgnoreCase) ||
    pathA.StartsWith(pathB + "\\", StringComparison.OrdinalIgnoreCase))
如果您的路径可能有尾随字符,您可以先将它们规范化,如下所示:

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

我使用了如下扩展方法:

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

if(pp.StartsWith(cp))
    return true;
else
    return false;
    /// <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('/','\\') + "/";
    }
//
///检查一个目录是否是另一个目录的基础
/// 
///候选根
///子文件夹
公共静态bool IsBaseOf(此DirectoryInfo根目录,DirectoryInfo子目录)
{
var directoryPath=EndsWithSeparator(新Uri(child.FullName.AbsolutePath);
var rootPath=EndsWithSeparator(新Uri(root.FullName.AbsolutePath);
返回directoryPath.StartsWith(rootPath,StringComparison.OrdinalIgnoreCase);
}
专用静态字符串EndsWithSeparator(字符串绝对路径)
{
返回绝对路径?.TrimEnd('/','\\')+“/”;
}

我建议使用“StartsWith”重载来忽略大小写。@Chad GetFullPath将以相同的大小写返回,因此如果
A
C:\my\dir
B
C:\my\dir2
,则忽略大小写将无法正确执行此操作?这应该是
false
,但我认为
Path.GetFullPath(B).StartsWith(Path.GetFullPath(A))
应该是
true
。您可以在实际目录名上附加结尾斜杠。然后从如果不区分大小写是否可行开始,这个答案可以取消固定吗?@jpmc26提到的边缘案例是一个严重的缺陷(-1)。@jrh我相信@pinkfloydx33的建议解决了这个答案中的问题。如果对答案进行编辑,将其包括在内,那就太好了,但是与这里发布的其他答案相比,
.StartsWith
似乎是一个体面、更简单的选择。更重要的是,其他答案并没有提供任何可靠的理由说明
.StartsWith
不起作用。@Charlie的第二高投票率答案没有说明为什么
.StartsWith
不起作用,它只是声明了它。@jrh正如您所发现的,GetFullPath处理“.”。只需执行
$“{input.TrimEnd(Path.directoryseportorchar)}{Path.directoryseportorchar)}”
即可解决尾部斜杠问题。我理解你为什么认为DirectoryInfo是一种“正确”的方式,但它的速度要慢得多,而且常常是不必要的。此外,
.StartsWith
似乎是一个直观的解决方案,我认为这个答案不应该得到负面分数。
IsBaseOf
似乎不适用于此。给定输入
'C:\somerandomdir'
'C:\someotherdir'
,我得到的是一个真实的结果。@jpmc26,这是因为您没有尾随斜杠。无法知道“somerandomdir”是目录名而不是文件名。如果您想处理这种情况,请在调用之前添加一个尾随斜杠。这有什么关系?无论如何,一个文件不能作为另一个文件的基础。为什么
IsBaseOf
甚至会做出这样一个奇怪的猜测,比如砍掉它认为是文件名的东西,而这显然不是调用方提出的问题?如果有这样的警告和奇怪的细节需要担心,你的答案至少应该解决它们。这是最安全和最好的解决方案沉迷于异常(不知道如何使用此方法)似乎是一种不好的做法。例如,假设该方法用于阻止从包含敏感数据的特定文件夹上载信息,现在当发生异常时,将上载数据。这也不适用于区分大小写的路径
IsubDirectoryOf(@“c:\a\b”,@“c:\a”)
返回FALSE此答案没有说明为什么看似显而易见的解决方案
.StartsWith
不起作用,而是说明了这一点,并解释了更复杂的解决方案(-1)请注意,如果尝试比较不同大小写的路径和其他一些边缘情况,则此方法不起作用,不幸的是,这两个目录都必须存在,才能使此方法正常工作,这是一个严重的限制。