Phillip Morton
Phillip Morton

Reputation: 244

Directory Enumerate to skip folder

I have this lovely bit of code that does a brilliant job for me, just grabs all the files I need for multiple searches etc.

public static IEnumerable<string> GetFiles(string path, string searchPatternExpression = "", SearchOption searchOption = SearchOption.AllDirectories)
{
    Regex reSearchPattern = new Regex(searchPatternExpression);
    return Directory.EnumerateFiles(path, "*", searchOption)
                    .Where(file => reSearchPattern.IsMatch(System.IO.Path.GetExtension(file)));
}

However there is one folder that I do not need the report to show in one of my directories. We'll call the folder "Narnia". I know there is a Directory.Skip but I am not entirely sure how to use it.

The command that calls the GetFiles(); is below. It just write out the returned list to a txt file. I wonder could I filter it from there?

internal static void GetFilesPassThrough(string SearchRoot, string extensions, string savepath) //GetFiles Regex Thread Start. 
{
    try
    {
        foreach (string file in GetFiles(SearchRoot, extensions))
            using (StreamWriter writer = new StreamWriter(savepath, true))
            {
                writer.WriteLine(file);
            }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message + savepath);
    }
}

Additional Information

As James has requested I will provide more in depth of how the code is called.

*Button is pressed which calls the GetFilesPassThrough(SearchDirectory, Extensions, savepath) * Extensions being what files I need reporting out of a directory, .PDF, .txt, .xls etc * As you can see above in the GetFilesPassThrough code, it Try's the GetFile() and returns each string called back in the List.

*Button > GetFilesPassThrough> Creates list with Get Files> And writes to textfile *

Upvotes: 2

Views: 1685

Answers (2)

Jim D&#39;Angelo
Jim D&#39;Angelo

Reputation: 3952

I don't know if you're looking to hard code a magic string somewhere or pass in via some sort of params, but you could do something like:

public static IEnumerable<string> GetFiles(
    string path, string searchPatternExpression = "",
    SearchOption searchOption = SearchOption.AllDirectories,
    params string[] toIgnore)
{
    Regex reSearchPattern = new Regex(searchPatternExpression);
    return Directory.EnumerateFiles(path, "*", searchOption)
                    .Where(file => reSearchPattern.IsMatch(System.IO.Path.GetExtension(file)))
                    .Where(file => !toIgnore.Contains(file));
}

(Of course this is simplistic, if you care about casing, but should be a start.)

Edit

If you want a case-insensitive search, you could change it to look like:

public static IEnumerable<string> GetFiles(
    string path, string searchPatternExpression = "",
    SearchOption searchOption = SearchOption.AllDirectories,
    params string[] toIgnore)
{
    var hash = new HashSet<string>(toIgnore, StringComparer.InvariantCultureIgnoreCase);
    Regex reSearchPattern = new Regex(searchPatternExpression);
    return Directory.EnumerateFiles(path, "*", searchOption)
                    .Where(file => reSearchPattern.IsMatch(System.IO.Path.GetExtension(file)))
                    .Where(file => !hash.Contains(file));
}

Edit 2

If you're looking to skip the directory with a given name, try:

public static IEnumerable<string> GetFiles(
    string path, string searchPatternExpression = "",
    SearchOption searchOption = SearchOption.AllDirectories,
    params string[] toIgnore)
{
    var hash = new HashSet<string>(toIgnore, StringComparer.InvariantCultureIgnoreCase);
    Regex reSearchPattern = new Regex(searchPatternExpression);
    return Directory.EnumerateDirectories(path, "*", searchOption)
                    .Where(folder => !hash.Contains(Path.GetDirectoryName(folder)))
                    .SelectMany(x => Directory.EnumerateFiles(x, "*", searchOption));
}

Note that this is going to ignore all subdirectories that match your ignore set.

Upvotes: 5

Craig Graham
Craig Graham

Reputation: 1191

 if (!(file.Contains("Narnia"))) writer.WriteLine(file)

Or am I being too simplistic and misunderstanding?

Upvotes: 2

Related Questions