views:

336

answers:

4

Every example I see seems to be for recursively getting files in subdirectories uses files only. What I'm trying to do is search a folder for a particular subdirectory named "xxx" then save that path to a variable so I can use it for other things.

Is this possible without looping through all the directories and comparing by name?

A: 

Yes, I believe that the only available solution (short of third party libraries) is a recursive search for the directory via name comparison.

jsight
A: 

You can use Windows Search which provides api for .Net too. Here is more detailed information: Windows Search 4.0 for Developers

Giorgi
+5  A: 

Well

Directory.GetDirectories(root);

will return you an array of the subdirectories.

You can then use Linq to find the one you're interested in:

IEnumerable<string> list = Directory.GetDirectories(root).Where(s => s.Equals("test"));

which isn't a loop in your code, but is still a loop nevertheless. So the ultimate answer is that "no you can't find a folder 'test' without looping".

You could add .SingleOrDefault() to the Linq, but that would depend on what you wanted to do if your "test" folder couldn't be found.

If you change the GetDirectories call to include the SearchOption SearchOption.AllDirectories then it will do the recursion for you as well. Obviously in this case the call could return more than one item if there was more than one folder named "test" in your directory tree.

ChrisF
+1 "This should only return one item." you could make that a contract by adding .SingleOrDefault() to the end of your statement :-) EDIT: and then obviously returning string. doh
David Archer
@David - indeed, though you might want to not return anything if the sub directory can't be found. I'll update my answer.
ChrisF
@ChrisF, yes the "..OrDefault" means null will be returned if no matching item is found. unless I missed a subtlety in what you were saying :-(
David Archer
@David - I was trying to say that the call would only return one item in the IEnumerable if "test" was found, but clearly failing. Is it any clearer now?
ChrisF
@ChrisF, my understanding: if you use IEnumerable then you get a list with either 1 item or no item. If you use SingleOrDefault then you get either the item or null? So yes, using IEnumerable saves them a null check if they're eg. populating a list of folders. And to play devil's advocate - singleorDefault is probably better if they're asking eg. does folder x exist kind of question :-)
David Archer
An enhancement in .NET 4 is Directory.EnumerateDirectories which does not force you to load the entire list of directories into an array. It returns an IEnumerable directly. There is also Directory.EnumerateFiles for files.
daddyman
I thought this would work, but I can't get it to work. My string list is only containing the first subdirectory and not a list of the others...
Brad
@Brad, what code are you using?
ChrisF
Well, this doesn't work:IEnumerable<string> snippetsList = Directory.GetDirectories(Application.StartupPath).Where(s => s.Equals("snippets"));It says System.Array does not contain a definition for 'Where'. So I tried this:IEnumerable<string> snippetsList = Directory.GetDirectories(Application.StartupPath, "*.*", SearchOption.AllDirectories)Trying to return every subdirectory (recursive) under my application path, it returns 2 entries (configuration and .settings) but there are a lot of subdirectories....\configuration\.settings (first one).\configuration\blah.\blah.\blah\blah
Brad
Sigh, nevermind, my second one works... I had forgot where my debug exe was running from...
Brad
@Brad - you'll need to add `using System.Linq` to get the `Where` as it's an extension method.
ChrisF
A: 

First of all, "No, it is not possible without looping through all the directories and comparing by name".

I believe your real question is "Is there an existing API which will handle looping through all the directories and comparing by name for me?"

Yes, there is. It's called Directory.Exists():

var xxxPath = Path.Combine(parentFolder, "xxx");
if (Directory.Exists(xxxPath))
    savedPath = xxxPath;
James Curran