Reputation: 13
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
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
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
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