80sRocker
80sRocker

Reputation: 327

Directory.EnumerateFiles method: How to enumerate files in specified subdirectories?

Assume the following directory structure. "C:\Genre" and the "Genre" directory having several subdirectories: "Rock", "Pop", "Metal", "Jazz".

How would I tweak the following statement to search in "Rock" and "Metal" subdirectories only?

var myFiles = Directory.
    EnumerateFiles("C:\Genre", "*", SearchOption.AllDirectories).
    Where(s => s.EndsWith(".jpg") || s.EndsWith(".gif"));

Upvotes: 1

Views: 3200

Answers (4)

jetstream96
jetstream96

Reputation: 146

Use Concat in Linq to combine the files in two directories.

var rockFiles = Directory.
EnumerateFiles("C:\Genre\Rock", "*", SearchOption.AllDirectories);
var metalFiles = Directory.
EnumerateFiles("C:\Genre\Metal", "*", SearchOption.AllDirectories);

var myFiles = rockFile
.Concat(metalFiles)
.Where(s => s.EndsWith(".jpg") || s.EndsWith(".gif"));

Upvotes: 1

Please consider some implementation like this one:

public static class Program
{
    public static void Main()
    {
        var directoryPaths = new List<string>
            {
                @"C:\root\path_1",
                @"C:\root\path_2",
                @"C:\root\path_3"
                // …
            };
        var searchPatterns = new List<string>
            {
                "*.jpg",
                "*.gif"
            };

        var filePaths = directoryPaths
            .SelectMany(directoryPath =>
                EnumerateFiles(directoryPath, searchPatterns, SearchOption.AllDirectories))
            .ToList()
            .AsReadOnly();

        // …
    }

    private static IEnumerable<string> EnumerateFiles(
        string path,
        IEnumerable<string> searchPatterns,
        SearchOption searchOption)
    {
        var filePaths = searchPatterns.SelectMany(
            searchPattern => Directory.EnumerateFiles(path, searchPattern, searchOption));
        return filePaths;
    }
}

Upvotes: 1

Tim Schmelter
Tim Schmelter

Reputation: 460118

You could use two arrays for the extensions and the Path-class:

var myFiles = Directory.EnumerateFiles(@"C:\Temp\Genre", "*", SearchOption.AllDirectories)
    .Where(fn => genres.Contains(Path.GetFileName(Path.GetDirectoryName(fn)), StringComparer.InvariantCultureIgnoreCase) 
          && extensions.Contains(Path.GetExtension(fn), StringComparer.InvariantCultureIgnoreCase));

Path.GetFileName(Path.GetDirectoryName(fn)) returns the folder-name of a file-path.

Upvotes: 0

Roman
Roman

Reputation: 1857

I'd say the clean way would be search each directory you want, and then add them up in the myFiles

var rockFiles = Directory.EnumerateFiles("c:\Genre\Rock", "*", SearchOption.AllDirectories).Where(s => s.EndsWith(".jpg") || s.EndsWith(".gif"));
var metalFiles = Directory.EnumerateFiles("c:\Genre\Metal", "*", SearchOption.AllDirectories).Where(s => s.EndsWith(".jpg") || s.EndsWith(".gif"));
var myFiles = RockFiles.Concat(MetalFiles);

Now, if you want a generic way to do so, that would be a different story, and a bit more complex one :)

Upvotes: 3

Related Questions