tags:

views:

134

answers:

5

How to read file name with dll extension from a directory and from its subfolders recursively using LINQ or LAMBDA expression.

Now i'm using Nested for-each loop to do this. Is there any way to do this using LINQ or LAMBDA expression?

+5  A: 

You don't need to use LINQ to do this - it's built into the framework:

string[] files = Directory.GetFiles(directory, "*.dll",
                                    SearchOption.AllDirectories);

or if you're using .NET 4:

IEnumerable<string> files = Directory.EnumerateFiles(directory, "*.dll",
                                                    SearchOption.AllDirectories);

To be honest, LINQ isn't great in terms of recursion. You'd probably want to write your own general-purpose recursive extension method. Given how often this sort of question is asked, I should really do that myself some time...

Jon Skeet
@Jon Skeet : thank you ...it includes the total path. I need only the name of the file like `foo.dll'
Pramodh
@Pramodh: So use `Path.GetFileName` as well.
Jon Skeet
It's worth noting these methods have serious flaws, however: if any I/O exception occurs, the entire result is aborted. In the GetFiles variant this means it generally returns no results whatsoever, and in the EnumerateFiles variant, enumeration will be halted whenever the first I/O error occurs (such as permission denied).
Eamon Nerbonne
Oh, and despite what the documentation says, enumerating GetFiles is *almost* always faster than enumerating EnumerateFiles - potentially excepting when the enumeration has a slow body or isn't completed (since EnumerateFiles starts faster).
Eamon Nerbonne
+1  A: 
IEnumerable<string> filenames = Directory.GetFiles(searchDirectory, "*.dll",
                                                   SearchOption.AllDirectories)
                                         .Select(s => Path.GetFileName(s));

Directory.GetFiles() returns the full path of files that match the specified search pattern in the specified directory. Select projects each element of fullpath sequence into a new form, only the filename.

madgnome
A: 

Reading files and directories is usually done with classes situated in the System.IO namespace. So the first step would consist into getting all the files that you need to read using the Directory.EnumerateFiles method and then for each file that corresponds to your search criteria read the contents using for example the File.ReadAllBytes method.

Darin Dimitrov
+1  A: 

If you really want to do it with a recursive lambda expression here you go:

Action<string, List<string>> discoverFiles = null;

discoverFiles = new Action<string, List<string>>((dir, list) =>
    {
        try
        {
            foreach (var subDir in Directory.GetDirectories(dir))
                discoverFiles(string.Concat(subDir), list);

            foreach (var dllFile in Directory.GetFiles(dir, "*.dll"))
            {
                var fileNameOnly = Path.GetFileName(dllFile);
                if (!list.Contains(fileNameOnly))
                    list.Add(fileNameOnly);
            }
        }
        catch (IOException)
        {
            // decide what to do here
        }
    });

// usage:
var targetList = new List<string>();
discoverFiles("c:\\MyDirectory", targetList);

foreach (var item in targetList)
    Debug.WriteLine(item);

Note: this is probably several times slower (and way harder to read/debug/maintain) than the previous answers, but it does not stop if there is an I/O exception somewhere.

Francesco De Vittori
It could do with some refactoring to separate concerns (primarily the recursive iteration from the filtering and adding to list), but I've used and benchmarked something similar for a home-grown file search; it performs almost as good as the built-in function (and that's when reading from cache - if I/O is uncached, there's no difference) - and it has the advantage of working even when some paths are too long or whatever.
Eamon Nerbonne
+1  A: 

this returns just file names+extensions:

DirectoryInfo di = new DirectoryInfo(@"d:\somewhere\");
var q = from i in di.GetFiles("*.dll", SearchOption.AllDirectories)
        select i.Name;

this returns just file names without extensions:

DirectoryInfo di = new DirectoryInfo(@"d:\somewhere\");
var q = from i in di.GetFiles("*.dll", SearchOption.AllDirectories)
        select System.IO.Path.GetFileNameWithoutExtension(i.Name);
syntaxcheck