GetFiles with multiple extensions
Solution 1
Why not create an extension method? That's more readable.
public static IEnumerable<FileInfo> GetFilesByExtensions(this DirectoryInfo dir, params string[] extensions)
{
if (extensions == null)
throw new ArgumentNullException("extensions");
IEnumerable<FileInfo> files = Enumerable.Empty<FileInfo>();
foreach(string ext in extensions)
{
files = files.Concat(dir.GetFiles(ext));
}
return files;
}
EDIT: a more efficient version:
public static IEnumerable<FileInfo> GetFilesByExtensions(this DirectoryInfo dir, params string[] extensions)
{
if (extensions == null)
throw new ArgumentNullException("extensions");
IEnumerable<FileInfo> files = dir.EnumerateFiles();
return files.Where(f => extensions.Contains(f.Extension));
}
Usage:
DirectoryInfo dInfo = new DirectoryInfo(@"c:\MyDir");
dInfo.GetFilesByExtensions(".jpg",".exe",".gif");
Solution 2
You can get every file, then filter the array:
public static IEnumerable<FileInfo> GetFilesByExtensions(this DirectoryInfo dirInfo, params string[] extensions)
{
var allowedExtensions = new HashSet<string>(extensions, StringComparer.OrdinalIgnoreCase);
return dirInfo.EnumerateFiles()
.Where(f => allowedExtensions.Contains(f.Extension));
}
This will be (marginally) faster than every other answer here.
In .Net 3.5, replace EnumerateFiles
with GetFiles
(which is slower).
And use it like this:
var files = new DirectoryInfo(...).GetFilesByExtensions(".jpg", ".mov", ".gif", ".mp4");
Solution 3
You can't do that, because GetFiles
only accepts a single search pattern. Instead, you can call GetFiles
with no pattern, and filter the results in code:
string[] extensions = new[] { ".jpg", ".tiff", ".bmp" };
FileInfo[] files =
dinfo.GetFiles()
.Where(f => extensions.Contains(f.Extension.ToLower()))
.ToArray();
If you're working with .NET 4, you can use the EnumerateFiles
method to avoid loading all FileInfo objects in memory at once:
string[] extensions = new[] { ".jpg", ".tiff", ".bmp" };
FileInfo[] files =
dinfo.EnumerateFiles()
.Where(f => extensions.Contains(f.Extension.ToLower()))
.ToArray();
Solution 4
You can use LINQ Union method:
dir.GetFiles("*.txt").Union(dir.GetFiles("*.jpg")).ToArray();
Solution 5
The following retrieves the jpg, tiff and bmp files and gives you an IEnumerable<FileInfo>
over which you can iterate:
var files = dinfo.GetFiles("*.jpg")
.Concat(dinfo.GetFiles("*.tiff"))
.Concat(dinfo.GetFiles("*.bmp"));
If you really need an array, simply stick .ToArray()
at the end of this.
Related videos on Youtube
rd42
Updated on August 06, 2020Comments
-
rd42 almost 4 years
Possible Duplicate:
Can you call Directory.GetFiles() with multiple filters?How do you filter on more than one extension?
I've tried:
FileInfo[] Files = dinfo.GetFiles("*.jpg;*.tiff;*.bmp"); FileInfo[] Files = dinfo.GetFiles("*.jpg,*.tiff,*.bmp");
-
Thomas Levesque over 13 yearsI guess you mean "more than one extension"... it doesn't work with two either
-
rd42 over 13 yearsyeup doesn't work for two either
-
John Saunders over 13 yearsBTW, are you aware that GetFiles is not related to C#, but only related to .NET?
-
Vikram almost 10 years@JohnSaunders, are you sure about this?
-
John Saunders almost 10 years@VikramNarkar: yes. You won't find it in the C# Reference, and it works equally well from VB.NET or any other CLR language.
-
Vikram almost 10 years@JohnSaunders, Thanks a lot!
-
-
Thomas Levesque over 13 yearsThat will be very inefficient if there are many files in the directory...
-
rd42 over 13 yearsThanks, I used the .NET 4 and got the following error. I'm new to this, so apologies is this is an obvious fix: Error 4 'bool' does not contain a definition for 'ToArray' and no extension method 'ToArray' accepting a first argument of type 'bool' could be found (are you missing a using directive or an assembly reference?)
-
Thomas Levesque over 13 yearsA closing bracket was missing, I fixed it
-
Thomas Levesque over 13 yearsYou don't need to create a separate instance of DirectoryInfo for each type... and there is a lot of repeated code, you should refactor that with a method. Anyway, I updated my answer to fix the error, did you try it ?
-
Cheng Chen over 13 yearsExactly.EnumerateFiles() is better at performance.
-
SLaks over 13 yearsThis is inefficient.
-
SLaks over 13 yearsIt would be faster to use a
HashSet<string>
. -
Thomas Levesque over 13 years@SLaks, perhaps, depending on the number of extensions... For only 3 extensions I don't think the difference is significant.
-
Cheng Chen over 13 years@Slaks: emm..it's better if I get all the files first and then filter it with different extensions.
-
SLaks over 13 yearsYes. See my answer. Also, you ought to call
SelectMany
instead ofConcat
:return extensions.SelectMany(dir.GetFiles);
-
Jeff Winn about 12 yearsRather than checking the extension as shown above, you can use the first example and pass the search pattern into EnumerateFiles and still be able to use checks against the filename rather than only being able to inspect the extension while retaining the efficiency of the 2nd example.
-
Doc Snuggles over 10 yearsTo avoid missing Capital Written Extensions I would add a StringComparer.OrdinalIgnoreCase to the Contains-Method.
return files.Where(f => extensions.Contains(f.Extension, StringComparer.OrdinalIgnoreCase));
-
Wessam El Mahdy over 7 yearsWorked for me, thanks.
-
Jeff almost 7 years@DocSnuggles +1 per C# Interactive window
> new[] { ".jpg", ".exe", ".gif" }.Contains(".GIF") false
and> new[] { ".jpg", ".exe", ".gif" }.Contains(".GIF", StringComparer.OrdinalIgnoreCase) true
-
Developer63 over 5 yearsFantastic solution, worked perfectly for me. I like that it's one line of code, the line is very readable and clear in its intent, I know what it's doing and why at a glance.
-
Oleksii Zhyglov over 5 yearsit is better to return array FilesInfo[], not collection, cause original method also returns n array:
-
Oleksii Zhyglov over 5 yearsstatic class ExtensionMethods { public static FileInfo[] GetFilesByExtensions(this DirectoryInfo dir, params string[] extensions) { if (extensions == null) throw new ArgumentNullException("extensions"); IEnumerable<FileInfo> files = dir.EnumerateFiles(); return files.Where(f => extensions.Contains(f.Extension)).ToArray(); } }
-
Dominic Isaia about 3 yearsI like this solution best because it's simple and easy to read.
-
Sid133 about 2 yearsFor me, having a single .xlsx file in the dir folder, the result is coming up as 2 .xlsx file with same name
-
Ievgen about 2 years@Sid133 how it can be? Union is performed on the different extensions.
-
Sid133 about 2 years@Ievgen No idea, i have posted problem statement here. stackoverflow.com/q/72041497/9304804