Reputation: 23119
How can I check whether a FileInfo object is a descendant of DirectoryInfo?
public bool IsFileDescendantOfDirectory(
FileInfo fileInfo,
DirectoryInfo directoryInfo)
{
}
Upvotes: 0
Views: 619
Reputation: 14962
After some back and forth with Tim Schmelter, I'm pretty sure that the following method is valid to determine whether or not a FileInfo
path lives under a DirectoryInfo
path:
public static bool IsFileBelowDirectory(FileInfo fileInfo, DirectoryInfo directoryInfo)
{
var separator = Path.DirectorySeparatorChar.ToString();
var directoryPath = string.Format("{0}{1}"
, directoryInfo.FullName
, directoryInfo.FullName.EndsWith(separator) ? "": separator);
return fileInfo.FullName.StartsWith(directoryPath, StringComparison.OrdinalIgnoreCase);
}
What is interesting is that you don't need to walk up the directories to check eaqulity at each level. This saves some time when your file is obviously not in the directory; for example for a directory C:\this\is\a\path\that\is\long
and a file C:\this\is\a\path\that\is\also\long.txt
walking up the directories would be a waste of checks since the difference is at the end of the path.
Upvotes: 1
Reputation: 460068
You can walk-up the parent directories:
public static bool IsFileDescendantOfDirectory(FileInfo fileInfo, DirectoryInfo directoryInfo)
{
// https://connect.microsoft.com/VisualStudio/feedback/details/777308/inconsistent-behavior-of-fullname-when-provided-path-ends-with-a-backslash
string path = directoryInfo.FullName.TrimEnd(Path.DirectorySeparatorChar);
DirectoryInfo dir = fileInfo.Directory;
while (dir != null)
{
if (dir.FullName.TrimEnd(Path.DirectorySeparatorChar).Equals(path, StringComparison.OrdinalIgnoreCase))
return true;
dir = dir.Parent;
}
return false;
}
Interesting, you have to compare the FullName
, DirectoryInfo.Equals
does not work as expected since it uses Object.Equals
which just compares references.
Upvotes: 5
Reputation: 444
This is enough:
public static bool IsDirectoryParent(DirectoryInfo directoryInfo, DirectoryInfo parentInfo)
{
if (!directoryInfo.Name.StartsWith(parentInfo.FullName))
return false;
return directoryInfo.FullName == parentInfo.FullName
|| IsDirectoryParent(directoryInfo.Parent, parentInfo);
}
public bool IsFileParent(FileInfo fileInfo, DirectoryInfo directoryInfo)
{
return IsDirectoryParent(fileInfo.Directory, directoryInfo);
}
Upvotes: -1
Reputation: 16609
You can check the parents of the file until it hits a matching directory. This will be quicker than searching the directory for the file:
public bool IsFileDescendantOfDirectory(DirectoryInfo directoryInfo, FileInfo fileInfo)
{
DirectoryInfo d = fileInfo.Directory;
do
{
if (d.FullName.Equals(directoryInfo.FullName, StringComparison.OrdinalIgnoreCase))
{
return true;
}
d = d.Parent;
}
while(d != null);
return false;
}
Upvotes: 2
Reputation: 6222
FileInfo gives a DirectoryInfo through its Directory property, and the DirectoryInfo gives a Parent property. So just;
DirectoryInfo fileOwner = myFileInfo.Directory;
do
{
if(fileOwner == mySampleDirectory) Debug.WriteLine("Yes !");
fileOwner = fileOwner.Parent;
}
while(fileOwner != null)
Upvotes: 0
Reputation: 101681
This would be an easy solution if you wanna look up for names:
Directory
.EnumerateFiles(di.FullName, *.*, SearchOption.AllDirectories)
.Any(x => x == fileInfo.FullName);
Upvotes: 0