代码之家  ›  专栏  ›  技术社区  ›  Thomas Levesque

directory.getparent中有错误吗?

  •  12
  • Thomas Levesque  · 技术社区  · 14 年前

    我的脸被 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 !!!
    

    我认为这是一个bug,但是这个方法从1.0开始就存在,所以我想现在应该已经检测到了。另一方面,如果它是按设计的,我想不出一个合理的解释,这样的设计…

    你怎么认为?是虫子吗?如果没有,你如何解释这种行为?

    3 回复  |  直到 11 年前
        1
  •  10
  •   GSerg    11 年前

    一些谷歌搜索显示 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 可以,因为您正以这种方式构造对象。


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

    尝试构造 FileInfo 对象退出 path2 . 你会发现它的构造是正确的, String.Empty 作为其名称和扩展名,不存在且具有 C:\foo\bar 作为其 DirectoryName . 鉴于此,情况是有意义的:这个“空文件”的父对象确实是 C:\Fo\bar .

        2
  •  3
  •   Russell McClure    14 年前

    我同意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;
        }
    }
    
        3
  •  1
  •   steinar Justin CI    14 年前

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

    C:\somenonexistingpath \ to \a \目录\

    被解释为到一个在目录中没有名称的文件的路径。这有点傻,但是如果我们假设微软的程序员希望得到一个文件的完整路径,那么不讨论这个问题是有意义的。

    编辑:

    注意

    C:\dir\makefile->C:\dir

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

    按预期给予家长。