Can you call Directory.GetFiles() with multiple filters?
If you have a large list of extensions to check you can use the following. I didn't want to create a lot of OR statements so i modified what lette wrote.
string supportedExtensions = "*.jpg,*.gif,*.png,*.bmp,*.jpe,*.jpeg,*.wmf,*.emf,*.xbm,*.ico,*.eps,*.tif,*.tiff,*.g01,*.g02,*.g03,*.g04,*.g05,*.g06,*.g07,*.g08";
foreach (string imageFile in Directory.GetFiles(_tempDirectory, "*.*", SearchOption.AllDirectories).Where(s => supportedExtensions.Contains(Path.GetExtension(s).ToLower())))
{
//do work here
}
How about this:
private static string[] GetFiles(string sourceFolder, string filters, System.IO.SearchOption searchOption)
{
return filters.Split('|').SelectMany(filter => System.IO.Directory.GetFiles(sourceFolder, filter, searchOption)).ToArray();
}
I found it here (in the comments): http://msdn.microsoft.com/en-us/library/wz42302f.aspx
For .NET 4.0 and later,
var files = Directory.EnumerateFiles("C:\\path", "*.*", SearchOption.AllDirectories)
.Where(s => s.EndsWith(".mp3") || s.EndsWith(".jpg"));
For earlier versions of .NET,
var files = Directory.GetFiles("C:\\path", "*.*", SearchOption.AllDirectories)
.Where(s => s.EndsWith(".mp3") || s.EndsWith(".jpg"));
edit: Please read the comments. The improvement that Paul Farry suggests, and the memory/performance issue that Christian.K points out are both very important.
for
var exts = new[] { "mp3", "jpg" };
You could:
public IEnumerable<string> FilterFiles(string path, params string[] exts) {
return
Directory
.EnumerateFiles(path, "*.*")
.Where(file => exts.Any(x => file.EndsWith(x, StringComparison.OrdinalIgnoreCase)));
}
- Don't forget the new .NET4
Directory.EnumerateFiles
for a performance boost (What is the difference between Directory.EnumerateFiles vs Directory.GetFiles?) - "IgnoreCase" should be faster than "ToLower" (
.EndsWith("aspx", StringComparison.OrdinalIgnoreCase)
rather than.ToLower().EndsWith("aspx")
)
But the real benefit of EnumerateFiles
shows up when you split up the filters and merge the results:
public IEnumerable<string> FilterFiles(string path, params string[] exts) {
return
exts.Select(x => "*." + x) // turn into globs
.SelectMany(x =>
Directory.EnumerateFiles(path, x)
);
}
It gets a bit faster if you don't have to turn them into globs (i.e. exts = new[] {"*.mp3", "*.jpg"}
already).
Performance evaluation based on the following LinqPad test (note: Perf
just repeats the delegate 10000 times)
https://gist.github.com/zaus/7454021
( reposted and extended from 'duplicate' since that question specifically requested no LINQ: Multiple file-extensions searchPattern for System.IO.Directory.GetFiles )