How to check whether a given path has child folders?

+2 votes
asked Aug 16, 2016 by Uwe Keim (860 points)

Currently, I'm using the Ftp.GetItems() extension method to get all items of a given path.

I'm looping the result item collection until I find the first item for which IsDirectory is true.

In pseudo-code:

public bool HasChildFolders(string path)
{
    var items = _ftp.GetItems(path);
    foreach ( var item in items )
    {        
        if ( item.IsDirectory ) return true;
    }

    return false;
}

Unfortunately, if the given path contains lots of child folders this takes ages to complete (I have folders with several 10k child folders).

So I'm searching for a faster way to check whether a folder contains at least one child folder.

My question:

How to quickly check whether a folder contains at least one child folder, even for a huge number of child folders?

Applies to: Rebex FTP/SSL

1 Answer

+1 vote
answered Aug 16, 2016 by Tomas Knopp (58,890 points)
selected Aug 16, 2016 by Uwe Keim
 
Best answer

Ftp.GetItems is a multi-file method that is by default recursive and the filtering is done at the client side. This means that it will try to search for any items even within all your subfolders. Considering you have thousands of folders at the server, this obviously makes it a really long lasting method call that consisting of thousands of FTP commands/response being sent/received by the FTP client. The recursive GetItems method is good for recursive/advanced listing of directory content, but for your task this is simply overkilling.

There are two possible solutions - either switch to the simple listing methods, e.g. GetList:

var items = Ftp.GetList(path);

or just tell the ftp.GetItems method to do a non-recursive search like this:

var items = ftp.GetItems(path, TraversalMode.NonRecursive);

You can also check this comparison of GetItems and GetList methods.

commented Aug 16, 2016 by Uwe Keim (860 points)
edited Aug 19, 2016 by Uwe Keim
Thanks, I'm already doing it non-recursively. I'll try the GetList() method.
commented Aug 16, 2016 by Tomas Knopp (58,890 points)
Ok! Let me know if the GetList helped.
commented Aug 19, 2016 by Uwe Keim (860 points)
I've switched to GetList and found no whatsoever improvement in terms of speed. So I'll stick for now with GetItems. Thanks again for your help!
commented Aug 19, 2016 by Tomas Knopp (58,890 points)
This is really strange, the GetList should be considerably quicker. Could you please create a log (https://www.rebex.net/kb/logging) from the attempt where you use GetList and then send the log file back to us for analysis? I'll look into what is causing the delay with GetList then.
commented Jan 2, 2018 by Uwe Keim (860 points)
Late update: Using Ants Performance Profiler I was able to detect that my (too) excessive logging was the primary reason that the HasChildFolders() call was so slow. I now temporarily disable logging when calling HasChildFolders() and later enable it again. While this is bad for hunting errors, it is good for performance.
commented Jan 2, 2018 by Lukas Matyska (55,430 points)
Great that you were able to find the cause of the issue.
You can also try to keep logging but in less verbosity. For example log only main operations and errors.
...