为什么GetDirectoryName为C:\返回null?

时间:2009-11-04 07:41:44

标签: .net

我刚刚遇到了一个看似奇怪的设计选择:

System.IO.Path.GetDirectoryName(@"C:\folder\file.ext")

返回“C:\ folder”

System.IO.Path.GetDirectoryName(@"C:\") 

返回null。

如果第一个示例返回“folder”,我可以更好地理解它。

任何想法为什么都是这种情况?当你只想获得文件夹路径时做了什么?

3 个答案:

答案 0 :(得分:5)

来自function's documentation

  

返回值类型:
A.   包含目录的字符串   路径的信息,或     null引用   (在Visual Basic中没有任何内容)if path   表示根目录   

(强调我加入)

答案 1 :(得分:1)

好的,我知道这个问题多年来一直没有被触及,但没有人真正回答过这个问题的原因?为什么会这样?'所以我要去对它采取长期的裂缝。

仅出于此解释的目的,路径是Windows的概念性事物。实际上,只有两种类型的路径。

  • 本地路径 - 以驱动器号C:\ Folder \ File.ext
  • 开头
  • 远程路径 - 从服务器和共享开始,\ Server \ Share \ Folder \ File.ext

我故意遗漏相对路径,因为所有相对路径都可以转换为上述两个路径之一的完整路径。

请考虑以下代码:

        var examplePaths = new[]
        {
            "C:\\Folder\\File.ext",
            "C:\\Folder\\",
            "C:\\Folder",
            "C:\\",
            "C:",
            "\\\\Server\\Share\\Folder\\File.ext",
            "\\\\Server\\Share\\Folder\\",
            "\\\\Server\\Share\\Folder",
            "\\\\Server\\Share\\",
            "\\\\Server\\Share",
            "\\\\Server\\",
            "\\\\Server",
            "\\\\",
        };

        foreach(var path in examplePaths)
        {
            var result = Path.GetDirectoryName(path) ?? "NULL";
            Console.WriteLine($"'{path}'\t'{result}'");
        }

如果你运行这个,我认为是一个有趣的模式:

 C:\Folder\File.ext                C:\Folder
 C:\Folder\                        C:\Folder 
 C:\Folder                         C:\ 
 C:\                               NULL 
 C:                                NULL 
 \\Server\Share\Folder\File.ext    \\Server\Share\Folder 
 \\Server\Share\Folder\            \\Server\Share\Folder 
 \\Server\Share\Folder             \\Server\Share 
 \\Server\Share\                   \\Server\Share 
 \\Server\Share                    NULL 
 \\Server\                         NULL 
 \\Server                          NULL 
 \\                                NULL 

让我们谈谈概念上的路径。首先一直到左边,是路径根。 C:\是一个根。 \ Server \ Share是一个根。 (查看GetRootLength源代码,了解它如何确定路径的哪一部分是根。)

查看上面的表格,我们看到返回null的所有内容都是一个根路径,或者是一个小于root的东西。

我们可以从概念上解决问题:

 C:\Folder\File.ext                Root\Directory\Filename
 C:\Folder\                        Root\Directory\ 
 C:\Folder                         Root\Directory
 C:\                               Root\ 
 C:                                Root 
 \\Server\Share\Folder\File.ext    Root\Directory\Filename
 \\Server\Share\Folder\            Root\Directory\ 
 \\Server\Share\Folder             Root\Directory
 \\Server\Share\                   Root\ 
 \\Server\Share                    Root 
 \\Server\                         Root 
 \\Server                          Root 
 \\                                Root 

我得到的是C:和\ Server \ Share都是root。并且' \' \ Server \ Share中的字符对该根具有特殊含义。你不能天真地只返回最后一个剩下的东西' \'字符。

如果查看GetDirectoryName source,您可以看到他们考虑到这一点,要求变量i大于根长度。

while (i > root && path[--i] != DirectorySeparatorChar && path[i] != AltDirectorySeparatorChar);

因此,如果您将此功能传递给类似于' C:\' path参数是一个独立的根。

现在,也许它不是最好的功能名称,但可以合理地将GetDirectoryName视为'获取包含此文件(或目录)的目录'当你以这种方式思考时,它突然变得有意义。也许GetParentDirectory可能是一个更好的名字。

获取包含C:\ Folder \ file.ext的目录,显而易见的结果是C:\ Folder。

获取包含C:\ Folder的目录,结果是C:\ contains Folder上的根目录。

获取包含C:\的目录,并且答案必须为NULL / nothing,因为根目录没有父目录。

答案 2 :(得分:0)

实际上,该函数更好地命名为GetPathName。它返回您传递的文件名目录的完整路径。