C# Searching for files and folders except in certain folders

19,171

Solution 1

No there isn't as far as I know. But you could use very simple LINQ to do that in a single line.

var s1 = Directory.GetFiles(path , "*.*", SearchOption.AllDirectories).Where(d => !d.StartsWith("<EXCLUDE_DIR_PATH>")).ToArray();

You can easily combine multiple exclude DIRs too.

Solution 2

You can't do exactly what you want with simple LINQ methods. You will need to write a recursive routine instead of using SearchOption.AllDirectories. The reason is that you want to filter directories not files.

You could use the following static method to achieve what you want:

public static IEnumerable<string> GetFiles(
    string rootDirectory,
    Func<string, bool> directoryFilter,
    string filePattern)
{
    foreach (string matchedFile in Directory.GetFiles(rootDirectory, filePattern, SearchOption.TopDirectoryOnly))
    {
        yield return matchedFile;
    }

    var matchedDirectories = Directory.GetDirectories(rootDirectory, "*.*", SearchOption.TopDirectoryOnly)
        .Where(directoryFilter);

    foreach (var dir in matchedDirectories)
    {
        foreach (var file in GetFiles(dir, directoryFilter, filePattern))
        {
            yield return file;
        }
    }
}

You would use it like this:

var files = GetFiles("C:\\SearchDirectory", d => !d.Contains("AvoidMe", StringComparison.OrdinalIgnoreCase), "*.*");

Why the added complexity? This method completely avoids looking inside directories you're not interested in. The SearchOption.AllDirectories will, as the name suggests, search within all directories.

If you're not familiar with iterator methods (the yield return syntax), this can be written differently: just ask!

Alternative

This has almost the same effect. However, it still finds files within subdirectories of the directories you want to ignore. Maybe that's OK for you; the code is easier to follow.

public static IEnumerable<string> GetFilesLinq(
    string root,
    Func<string, bool> directoryFilter,
    string filePattern)
{
    var directories = Directory.GetDirectories(root, "*.*", SearchOption.AllDirectories)
        .Where(directoryFilter);

    List<string> results = new List<string>();

    foreach (var d in directories)
    {
        results.AddRange(Directory.GetFiles(d, filePattern, SearchOption.TopDirectoryOnly));
    }

    return results;
}
Share:
19,171
Jaswanth Kumar
Author by

Jaswanth Kumar

Updated on June 09, 2022

Comments

  • Jaswanth Kumar
    Jaswanth Kumar almost 2 years

    Is there any way to exclude certain directories from SearchOption using LINQ command like this

    string path = "C:\SomeFolder";
    
    var s1 = Directory.GetFiles(path , "*.*", SearchOption.AllDirectories);
    
    var s2 = Directory.GetDirectories(path , "*.*", SearchOption.AllDirectories);
    

    The path consists of Sub1 and Sub2 Folders with certain files in it. I need to exclude them from directory search.

    Thanks

    This Worked:

    string[] exceptions = new string[] { "c:\\SomeFolder\\sub1",
    "c:\\SomeFolder\\sub2" };
    
    var s1 = Directory.GetFiles("c:\\x86", "*.*",
    SearchOption.AllDirectories).Where(d => exceptions.All(e =>
    !d.StartsWith(e)));
    

    This helped with Exceptions

  • Olly
    Olly over 10 years
    Here you're actually filtering the returned files, not the directories.
  • Lonli-Lokli
    Lonli-Lokli over 10 years
    Like your nice xample most of all
  • dotNET
    dotNET almost 8 years
    @Olly: GetFiles() returns fully qualified paths of all files, so doing a Where with StartsWith() will essentially return what the OP is looking for.
  • Olly
    Olly almost 8 years
    Ah, yes. Nice and simple!