Directory.GetParent中的错误?

时间:2010-10-18 22:47:03

标签: .net base-class-library

我被System.IO.Directory.GetParent方法的一种非常奇怪的行为击中了脸:

string path1 = @"C:\foo\bar";
DirectoryInfo parent1 = Directory.GetParent(path1);
Console.WriteLine (parent1.FullName); // Prints C:\foo, as expected

// Notice the extra backslash. It should still refer to the same location, right ?
string path2 = @"C:\foo\bar\";
DirectoryInfo parent2 = Directory.GetParent(path2);
Console.WriteLine (parent2.FullName); // Prints C:\foo\bar !!!

我认为这是一个错误,但是这个方法自1.0以来一直存在,所以我猜它现在已经被检测到了。另一方面,如果它是按照设计的,我想不出对这种设计的明智解释......

你怎么看?这是一个错误吗?如果没有,你如何解释这种行为?

3 个答案:

答案 0 :(得分:10)

一些谷歌搜索显示some thoughts

DirectoryInfo di = new DirectoryInfo(@"C:\parent\child");
Console.WriteLine(di.Parent.FullName);
     

DirectoryInfo di = new DirectoryInfo(@"C:\parent\child\");
Console.WriteLine(di.Parent.FullName);
     

两者都返回“C:\ parent”

     

我只能假设Directory.GetParent(...)不能假设C:\parent\child是目录而不是没有文件扩展名的文件。 DirectoryInfo可以,因为你正在以这种方式构建对象。


我个人认为当有反斜杠时,该字符串被视为目录内“null文件”的路径(即没有名称和扩展名的文件)。显然,那些可以存在(应该有一个链接,但由于某种原因,我找不到任何东西)。

尝试从FileInfo构建path2个对象。您会看到它已正确构建,String.Empty作为其名称和扩展名,不存在且C:\foo\bar为其DirectoryName。鉴于此,情况是有道理的:这个“空文件”的父对象确实是C:\foo\bar

答案 1 :(得分:3)

我同意GSerg。只是为了增加一些额外的火力,我将添加以下使用Reflector获得的代码片段。

Directory.GetParent函数基本上只调用Path.GetDirectoryName函数:

[SecuritySafeCritical]
public static DirectoryInfo GetParent(string path)
{
    if (path == null)
    {
        throw new ArgumentNullException("path");
    }
    if (path.Length == 0)
    {
        throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"), "path");
    }
    string directoryName = Path.GetDirectoryName(Path.GetFullPathInternal(path));
    if (directoryName == null)
    {
        return null;
    }
    return new DirectoryInfo(directoryName);
}

DirectoryInfo的Parent属性基本上剥离了一个尾部斜杠,然后调用Path.GetDirectoryName:

public DirectoryInfo Parent
{
    [SecuritySafeCritical]
    get
    {
        string fullPath = base.FullPath;
        if ((fullPath.Length > 3) && fullPath.EndsWith(Path.DirectorySeparatorChar))
        {
            fullPath = base.FullPath.Substring(0, base.FullPath.Length - 1);
        }
        string directoryName = Path.GetDirectoryName(fullPath);
        if (directoryName == null)
        {
            return null;
        }
        DirectoryInfo info = new DirectoryInfo(directoryName, false);
        new FileIOPermission(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, info.demandDir, false, false).Demand();
        return info;
    }
}

答案 2 :(得分:1)

这非常有趣。首先,当我读到这篇文章时,我很确定这会是一个错误,但当我想到它有点长时间时,我得出的结论是可能意图是路径不应该是一个目录但是文件的完整路径或相对路径。所以

  

C:\ somenonexistingpath \到\ A \目录\

被解释为... \目录中没有名称的文件的路径。这有点愚蠢,但如果我们假设微软的程序员期望文件的完整路径,那么就不应该覆盖这种情况。

编辑:

请注意

  

c:\ dir \ makefile - > C:\ DIR

     

c:\ dir \ build.msbuild - > C:\ DIR

按预期给予父母。