HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Get list of files in directory with exclude option

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
directorywithoptiongetfileslistexclude

Problem

This method returns the list of files (absolute path) in a folder (or tree). It allows filtering by extensions or filenames.

The method receives the following parameters:

  • string path: folder path to scan for files.



  • string[] exclude: can contain filenames such as "read.me" or extensions such as "*.jpg".



  • SearchOption searchOption: TopDirectoryOnly to scan only the specified folder or AllDirectories to scan tree folder under the specified path.



The method return files that doesn't appear in exclude array and a) hasn't extension, or b) extension doesn't appear in exclude array.

public static IEnumerable GetFiles(string path, string[] exclude, SearchOption searchOption = SearchOption.AllDirectories)
    {
        IEnumerable files = Directory.EnumerateFiles(path, "*.*", searchOption);
        var resultFiles = new List();

        if (exclude.Length > 0)
        {
            foreach (var filename in files)
            {
                string extension = Path.GetExtension(filename);

                if (Array.IndexOf(exclude, Path.GetFileName(filename)) >= 0)
                {
                    continue;
                }

                if (string.IsNullOrEmpty(extension) || Array.IndexOf(exclude, "*" + extension) < 0)
                {
                    resultFiles.Add(filename);
                }
            }
        }

        return resultFiles;
    }

Solution

You're already returning an IEnumerable so you might as well turn it into an iterator block. Discard the local resultFiles and simply use yield return filename.

MSDN on yield

I don't like that both filenames and extensions are in the same array. If you have 1 extension and 5000 files that have to be excluded, it will iterate over 5000 files (if you have bad luck) for no reason.

I would consider using the .Contains() extension method: it's just more expressive than Array.IndexOf and should be no difference in performance.

I prefer string.IsNullOrWhiteSpace since that also takes care of.. well.. whitespace. You never know if the pesky QA departement tries something like that.

IEnumerable files = Directory.EnumerateFiles(path, "*.*", searchOption);

if (exclude.Length > 0)
{
}

return resultFiles;


If there is nothing to exclude, you won't include anything either.

A new implementation might look like this:

public static IEnumerable GetFiles(string path, IEnumerable excludedFiles, IEnumerable excludedExtensions, SearchOption searchOption = SearchOption.AllDirectories)
{
    var files = Directory.EnumerateFiles(path, "*.*", searchOption);

    foreach(var file in files)
    {
        if(excludedFiles.Contains(file))
        {
            continue;
        }

        if(excludedExtensions.Contains(Path.GetExtension(file)))
        {
            continue;
        }

        yield return file;
    }
}

Code Snippets

IEnumerable<string> files = Directory.EnumerateFiles(path, "*.*", searchOption);

if (exclude.Length > 0)
{
}

return resultFiles;
public static IEnumerable<string> GetFiles(string path, IEnumerable<string> excludedFiles, IEnumerable<string> excludedExtensions, SearchOption searchOption = SearchOption.AllDirectories)
{
    var files = Directory.EnumerateFiles(path, "*.*", searchOption);

    foreach(var file in files)
    {
        if(excludedFiles.Contains(file))
        {
            continue;
        }

        if(excludedExtensions.Contains(Path.GetExtension(file)))
        {
            continue;
        }

        yield return file;
    }
}

Context

StackExchange Code Review Q#87662, answer score: 7

Revisions (0)

No revisions yet.