Directory.GetParent 中的错误?

发布于 2024-09-28 04:49:45 字数 588 浏览 1 评论 0原文

我被 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 就已经存在了,所以我想它会目前已被检测到。另一方面,如果它是按照设计的,我想不出对这样的设计合理的解释......

你觉得怎么样?这是一个错误吗?如果不是,你如何解释这种行为?

I was hit in the face by a very weird behavior of the System.IO.Directory.GetParent method:

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 !!!

I would consider it a bug, but this method has been there since 1.0, so I guess it would have been detected by now. On the other hand, if it's as designed, I can't think of a sensible explanation for such a design...

What do you think ? Is it a bug ? If not, how do you explain this behavior ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吻泪 2024-10-05 04:49:45

一些谷歌搜索揭示了一些想法

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 可以,因为您正在以这种方式构造对象。


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

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

Some googling reveals some thoughts:

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

and

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

Both return "C:\parent"

I can only assume Directory.GetParent(...) can't assume that C:\parent\child is a directory instead of a file with no file extension. DirectoryInfo can, because you're constructing the object that way.


Personally what I think is that when there is a backslash, the string is treated as a path to the "null file" inside the directory (that is, a file with no name and extension). Apparently, those can exist (there should be a link, but for some reason I can't find anything).

Try constructing a FileInfo object out of path2. You'll see it's properly constructed, has String.Empty as its name and extension, does not exist and has C:\foo\bar as its DirectoryName. Given that, the situation makes sense: the parent object for this "null file" is indeed C:\foo\bar.

请恋爱 2024-10-05 04:49:45

我同意 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;
    }
}

I agree with GSerg. Just to add some additional firepower, I'm going to add the following code snippets obtained with Reflector.

The Directory.GetParent function basically just calls the Path.GetDirectoryName function:

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

The Parent property of the DirectoryInfo basically strips off a trailing slash and then calls 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;
    }
}
素染倾城色 2024-10-05 04:49:45

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

c:\somenonexistingpath\to\a\directory\

被解释为 ...\directory 中没有名称的文件的路径。这有点愚蠢,但如果我们假设 Microsoft 的程序员期望文件的完整路径,那么不讨论这种情况是有意义的。

编辑:

请注意

c:\dir\makefile -> c:\目录

c:\dir\build.msbuild -> c:\目录

按预期提供父级。

This is pretty interesting. First when I read this I was pretty sure this would be a bug, but when I thought a little bit longer about it I came to the conclusion that probably the intent is that path should not be a directory but a full or relative path to a file. So

c:\somenonexistingpath\to\a\directory\

gets interpreted as a path to a file with no name in ...\directory. That's kind of silly, but if we assume that the programmers at Microsoft were expecting a full path to a file, it makes sense not to cover this case.

EDIT:

Note that

c:\dir\makefile -> c:\dir

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

give the parent as expected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文