Faker
Faker

Reputation: 13

How can I either get an array of files or count files based of multiple conditions

I have been browsing all over and I can't seem to find any answers that relate to me specifically.

I'm trying to either return an array of files or count files in a folder based off multiple conditions.

Something similar to this: how search file with multiple criteria of extension of file

However, I'm not looking to search based of file extension only but also file names.

For example:

If I have the following files in a folder:

test1.mp3

test2.avi

test1.jpg


How can I search for all files containing "1". The trick is that users can dynamically add conditions to check for in the file name. So it can't be something like this: dInfo.GetFilesByExtensions(".jpg",".exe",".gif");

The conditions will be added to an array of conditions.

So if the user now also searches for files containing "1" and "t". I would like it to return either "2" (so as a count) or as an array of these files for example, x being the code.

string[] files = x

after the code executes, the files array will look like this:

files[0] = "C:\test1.mp3"; files[1] = "C:\test1.jpg";

Upvotes: 0

Views: 1021

Answers (3)

chomba
chomba

Reputation: 1451

You could define an extension method, like this:

public static IEnumerable<string> SearchByName(this DirectoryInfo dir, List<string> keywords)
{
    foreach (FileInfo file in dir.EnumerateFiles())
    {
        string fileName = Path.GetFileNameWithoutExtension(file.Name);

        if (keywords.All(keyword => fileName.Contains(keyword)))
        {
            yield return file.FullName;
        }
    }
}

Here's the query expression equivalent:

var dir = new DirectoryInfo(@"E:\folder");
var keywords = new List<string> { "test", "5" };

var query = from fileInfo in dir.EnumerateFiles()
            let fileName = Path.GetFileNameWithoutExtension(fileInfo.Name)
            where keywords.All(keyword => fileName.Contains(keyword))
            select fileInfo;

foreach (var fileInfo in query)
{
    Console.WriteLine(fileInfo.FullName);
}

Upvotes: 0

Jacob Roberts
Jacob Roberts

Reputation: 1825

There is no magic way to do this. The best thing I can think of is have specific filters for the search criteria and use linq to filter.

First get a list of all files in a folder var files = Directory.GetFiles(folder); That also has an extension method where you can wildcard search like var files = Directory.GetFiles(folder, "*.exe"); Now with your filters in mind, this can be an enum for a specific action and a search string. Specific actions like; contains, starts with, ends with...

var files = Directory.GetFiles(folder).Select(Path.GetFileName); //returns only file names
foreach (var filter in filters) 
{
    switch (filter.Action)
    {
        case "contains":
            files = files.Where(f => f.Contains(filter.SearchString));
            break;
        case "next action":
            //filter here
            break;
    }
}

If you want to simplify it in a more magical way, you can use something like var files = Directory.GetFiles(folder, "begin*middle*end*.ex*"); But for something more accurate, this will not work, use the long winded previous mentioned.

Upvotes: 0

Rufus L
Rufus L

Reputation: 37050

You could do some version of the following:

var folderToSearch = "d:\\public";
var nameContains = "1";

var filesMeetingCriteria = new DirectoryInfo(folderToSearch)
    .GetFiles()
    .Where(file => file.Name.Contains(nameContains));

Or, to use a list of conditions, where the file name has to contain all the conditions (but not in any specific order):

var folderToSearch = "d:\\public";
var nameConditions = new List<string> {"r", "t"};

var filesMeetingCriteria =
    new DirectoryInfo(folderToSearch)
        .GetFiles()
        .Where(file =>
            nameConditions.All(condition =>
                file.Name.IndexOf(condition) > -1))
        .ToList();

// To verify the results:
filesMeetingCriteria.ForEach(file => Console.WriteLine(file.Name));

And you can do case-insensitive comparisons using:

var filesMeetingCriteria =
    new DirectoryInfo(folderToSearch)
        .GetFiles()
        .Where(file =>
            nameConditions.All(condition =>
                file.Name.IndexOf(condition,
                    StringComparison.OrdinalIgnoreCase) > -1))
        .ToList();

Upvotes: 1

Related Questions