I was hit in the face by a very weird behavior of the System.IO.Directory.GetParent
method:
string path1 = @\"C:\\foo\\bar\";
DirectoryInfo pare
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;
}
}
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.
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 thatC:\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
.