C# Searching for files and folders except in certa

2019-01-15 20:42发布

问题:

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

回答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.



回答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;
}


回答3:

try this

 var s2 =  Directory.GetDirectories(dirPath, "*", SearchOption.AllDirectories)
         .Where(directory => !directory.Contains("DirectoryName"));


回答4:

///used To Load Files And Folder information Present In Dir In dir
private void button1_Click(object sender, EventArgs e)
    {
        FileInfo[] fileInfoArr;
        StringBuilder sbr=new StringBuilder();
        StringBuilder sbrfname = new StringBuilder();
        string strpathName = @"C:\Users\prasad\Desktop\Dll";
        DirectoryInfo dir = new DirectoryInfo(strpathName);
        fileInfoArr = dir.GetFiles("*.dll");

        //Load Files From RootFolder
        foreach (FileInfo f in fileInfoArr)
        {
            sbrfname.AppendLine(f.FullName);
        }
        DirectoryInfo[] dirInfos = dir.GetDirectories("*.*");
       //Load Files from folder folder 
        foreach (DirectoryInfo d in dirInfos)
        {
           fileInfoArr = d.GetFiles("*.dll");
           foreach (FileInfo f in fileInfoArr)
           {
               sbrfname.AppendLine(f.FullName);
           }
            sbr.AppendLine(d.ToString());

        }
        richTextBox1.Text = sbr.ToString();
        richTextBox2.Text = sbrfname.ToString();
    }