divinci
divinci

Reputation: 23119

Is FileInfo a descendant of DirectoryInfo

How can I check whether a FileInfo object is a descendant of DirectoryInfo?

public bool IsFileDescendantOfDirectory(
    FileInfo fileInfo,
    DirectoryInfo directoryInfo)
{

}

Upvotes: 0

Views: 619

Answers (6)

samy
samy

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

Tim Schmelter
Tim Schmelter

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

Ciprian Khlud
Ciprian Khlud

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

Rhumborl
Rhumborl

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

PhillipH
PhillipH

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

Selman Genç
Selman Genç

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

Related Questions