Can you call Directory.GetFiles() with multiple filters?
Asked Answered
G

28

418

I am trying to use the Directory.GetFiles() method to retrieve a list of files of multiple types, such as mp3's and jpg's. I have tried both of the following with no luck:

Directory.GetFiles("C:\\path", "*.mp3|*.jpg", SearchOption.AllDirectories);
Directory.GetFiles("C:\\path", "*.mp3;*.jpg", SearchOption.AllDirectories);

Is there a way to do this in one call?

Groningen answered 2/10, 2008 at 15:58 Comment(4)
As a side note , using GetFiles search pattern for filtering the extension is not safe.For instance you have two file Test1.xls and Test2.xlsx and you want to filter out xls file using search pattern *.xls, but GetFiles return both Test1.xls and Test2.xlsx . Read Note Section for more infoHigherup
So how to prevent this?Protactinium
@Higherup How is that not safe? That looks like a feature rather than a bug.Abdella
So how to prevent this? Use ?.xls will correctly filter xls files only and will not, for example, include xlsx files.Sinistrodextral
F
623

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.

Fadein answered 2/10, 2008 at 16:9 Comment(13)
Just make sure that you understand the implications though: this will return all files in a string array and then filter that by the extensions you specify. That might not be a big issue if "C:\Path" doesn't have lot of files underneath it, but may be a memory/performance issue on "C:\" or something like that.Entente
... 2 years later: Nice code, but watch out with this, if you have a file that ends with .JPG it won't make it. Better add s.ToLower().Endswith...Merovingian
you could just use s.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)Establishmentarian
To cut down on the or conditions I like to do the following (although I'm not sure if there is more of a performance impact)... var files = myDirInfo.GetFiles().Where(o => new[]{"mp3", "jpg"}.Contains(o.Extension.ToLower()).ToArray();Metalloid
Note that with .NET 4.0, you can replace Directory.GetFiles with Directory.EnumerateFiles, msdn.microsoft.com/en-us/library/dd383571.aspx, which will avoid the memory issues that @Entente mentions.Rustler
@MattWinward you should read msdn.microsoft.com/en-us/library/dd465121.aspxGonadotropin
I made some performance improvements and provide comparison code at the answer below: #163662Pantheism
@MAC It's the parameter of the lambda expression, in this case s represents each file name returned from the call to Directory.EnumerateFiles/Directory.GetFiles.Fadein
If you want to improve performance even further in case of many possible extensions, it's better to create a HashSet with all extensions and do Where(f => _validExtensions.Contains(Path.GetExtension(f).ToLower())). Basically Contains is much faster than performing string comparisons multiple times.Tengdin
GetFiles method is much faster than EnumerateFilesEuphuism
In context of data, you first want all files then you filter them.Endblown
@IlyaChernomordik: The problem with .Contains is it includes files that have no extension.Vaporization
Note that you may not always want to use EnumerateFiles rather than GetFiles; for example if you want to process the files in a specific order you want to have the whole file set to determine this order before you start processing.Ottie
H
68

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

Homespun answered 11/12, 2011 at 19:55 Comment(7)
I'm guessing this avoids the potential memory pitfalls of the top rated answer? In which case, it should be rated higher!Frescobaldi
@DanW The top rated answer surely puts burden on the memory but I think that shouldn't be such a problem. I liked this answer too, but it's actually (much) slower then the accepted answer. Check this SpeedTestCardiogram
Thanks. Glad to see it's only about twice as slow - I'll stick with it for the meantime I think.Frescobaldi
It is only twice as slow if there are only two extensions. If you have a list of X extensions, then it will be X times more slow. Because here you are calling the function Directory.GetFiles several times, whereas in the other solution it is called only once.Tapes
@OscarHermosilla One can use Parallel.ForEach to get them in parallelOrsino
@Orsino but then you're limited by IO bandwidthChilt
@Cardiogram bad link.Pooch
A
41

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
}
Antonio answered 6/1, 2011 at 16:36 Comment(7)
Help me with this please...When I print imageFile it's giving total path of it.How can I shrink it to just the name of the file.Nad
System.IO.Path.GetFileName(imageFile)Antonio
Path.GetExtension returns '.ext', not '*.ext' (at least in 3.5+).Sensuous
FYI: You need System.Linq for .where(Antonio
Why use a comma as a separation character? A forbidden character like a | would be more reliable. You would exclude the (rare) case where an extension contains a comma at the end.Sixfold
There is a potential flaw. We are long past the days where extensions are required to be exactly three characters. Suppose you might encounter a file with .abc, and supportedExtensions contains .abcd. Will match, though it should not. To fix: supportedExtensions = ".jpg|.abcd|"; with .Contains(Path.GetExtension(s).ToLower() + "|"). That is, include your separator character in the test. IMPORTANT: your separator character must also be after the LAST entry in supportedExceptions.Marler
Another flaw is that all .Contains solutions include files that have no extension.Vaporization
P
35

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)));
}

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 )

Pantheism answered 13/11, 2013 at 18:39 Comment(10)
what do you mean by "i gets a bit faster if you don't have to turn them into globs"? Is it O(1) or is it O(n) (in regards to number of files, not number of extensions)? I would have guessed it's O(1) (or O(n) in regards to number of extensions) and probably somewhere in the range of a few cpu-cycles... If that's the case it's probably - performance wise - negligiblePedagogy
@Pedagogy yeah with 10k reps against 2 extensions the glob vs. str difference is 3ms, so yes technically negligible (see perf results link), but not knowing how many extensions you need to filter for i figured it's worth pointing out that there is a difference; i leave it up to you to decide if "simplified usage" (i.e. .FilterFiles(path, "jpg", "gif")) is better than "explicit globs" (i.e. .FilterFiles(path, "*.jpg", "*.gif")).Pantheism
perfect, thanks. Sorry i somehow skipped over that github link. Maybe i should adapt my screen color settings :)Pedagogy
Does this support uppercase extension such ass .JPG or .MKV?Memorize
@Memorize You'll notice in my first example StringComparison.OrdinalIgnoreCase means it would work for .jpg or .Jpg or .JPG, etcPantheism
The flaw with the SelectMany solution is that it will iterate over all the files once per file extension passed in.Audition
@17of26 good call, thanks for pointing it out. It's funny because I just ran into this case yesterday as well, and only noticed because I had a bunch of files with "multiple extensions" (e.g. .json.html) that matched more than one glob.Pantheism
@17of26 But, I'm guessing/hoping that because it's more of a filesystem thing with the glob that it's not really iterating every file in the directory, at least not in the traditional sense.Pantheism
There's a gotcha with EnumerateFiles wherein matching 3-character extensions like *.htm will also match *.html or really anything that has .htm in it (e.g. .htmfoo). This seems to be related to old DOS 8.3 filenames. codeproject.com/Questions/152289/… See note about searchPattern here: learn.microsoft.com/en-us/dotnet/api/…Diatribe
@MichaelHaren i can't reproduce that locally in LinqPad 6 or in dotnetfiddle.net/U1zkoI (v4.7.2) -- is it tied to a specific version of .NET?Pantheism
B
19

I know it's old question but LINQ: (.NET40+)

var files = Directory.GetFiles("path_to_files").Where(file => Regex.IsMatch(file, @"^.+\.(wav|mp3|txt)$"));
Biak answered 17/10, 2012 at 4:18 Comment(1)
Good idea. Consider using file.ToLower() to easily match upper-case extensions. And why not extract the extension first, so Regex doesn't have to examine entire path: Regex.IsMatch(Path.GetExtension(file).ToLower(), @"\.(wav|mp3|txt)");Marler
C
16

There is also a descent solution which seems not to have any memory or performance overhead and be quite elegant:

string[] filters = new[]{"*.jpg", "*.png", "*.gif"};
string[] filePaths = filters.SelectMany(f => Directory.GetFiles(basePath, f)).ToArray();
Cockroach answered 22/3, 2013 at 13:3 Comment(2)
I suppose I could edit it so that it would accept unknown unlimited number of extensions with new string variable and a Split function. But even then, how is this better than jnoreiga's solution? Is it faster? Less memory consuming?Protactinium
There is a trade-off. This approach calls GetFiles multiple times, one per filter. Those multiple calls might be significant "performance overhead" in some situations, It does have the important advantage that each GetFiles only returns an array with the matching file paths. I would expect this to usually be a good performance result, maybe even superior performance, but that needs to be tested. If GetFiles is significantly faster than EnumerateFiles, then this may be the best approach yet. Also note that the final ".ToArray()" can be omitted when IEnumerable is useable directly.Marler
P
11

Another way to use Linq, but without having to return everything and filter on that in memory.

var files = Directory.GetFiles("C:\\path", "*.mp3", SearchOption.AllDirectories).Union(Directory.GetFiles("C:\\path", "*.jpg", SearchOption.AllDirectories));

It's actually 2 calls to GetFiles(), but I think it's consistent with the spirit of the question and returns them in one enumerable.

Poulson answered 2/12, 2011 at 22:31 Comment(2)
Why use Linq, then? Would it be faster than using a List and addrange?Handmaiden
i don't know what would be faster and don't think it's an important question. for almost any place you'd be using the code for any solution to this problem, the difference in performance would be negligible. the question should be as to what is more readable to ease the maintainability of the code in the future. i think this is a reasonable answer because it puts into one source line, which i think is part of what the question desires, the calls necessary and clearly expresses the intent of that line. list and addrange is distracting with multiple steps to accomplish the same thing.Poulson
T
10

Let

var set = new HashSet<string>(
    new[] { ".mp3", ".jpg" },
    StringComparer.OrdinalIgnoreCase); // ignore case
var dir = new DirectoryInfo(path);

Then

dir.EnumerateFiles("*.*", SearchOption.AllDirectories)
   .Where(f => set.Contains(f.Extension));

or

from file in dir.EnumerateFiles("*.*", SearchOption.AllDirectories)
from ext in set // makes sense only if it's just IEnumerable<string> or similar
where String.Equals(ext, file.Extension, StringComparison.OrdinalIgnoreCase)
select file;
Toor answered 14/9, 2010 at 8:16 Comment(1)
getfiles do not have the overload u posted.Drug
E
7

Nope. Try the following:

List<string> _searchPatternList = new List<string>();
    ...
    List<string> fileList = new List<string>();
    foreach ( string ext in _searchPatternList )
    {
        foreach ( string subFile in Directory.GetFiles( folderName, ext  )
        {
            fileList.Add( subFile );
        }
    }

    // Sort alpabetically
    fileList.Sort();

    // Add files to the file browser control    
    foreach ( string fileName in fileList )
    {
        ...;
    }

Taken from: http://blogs.msdn.com/markda/archive/2006/04/20/580075.aspx

Elecampane answered 2/10, 2008 at 16:6 Comment(0)
R
6

I can't use .Where method because I'm programming in .NET Framework 2.0 (Linq is only supported in .NET Framework 3.5+).

Code below is not case sensitive (so .CaB or .cab will be listed too).

string[] ext = new string[2] { "*.CAB", "*.MSU" };

foreach (string found in ext)
{
    string[] extracted = Directory.GetFiles("C:\\test", found, System.IO.SearchOption.AllDirectories);

    foreach (string file in extracted)
    {
        Console.WriteLine(file);
    }
}
Rash answered 26/11, 2011 at 17:2 Comment(0)
C
5
List<string> FileList = new List<string>();
DirectoryInfo di = new DirectoryInfo("C:\\DirName");

IEnumerable<FileInfo> fileList = di.GetFiles("*.*");

//Create the query
IEnumerable<FileInfo> fileQuery = from file in fileList
                                  where (file.Extension.ToLower() == ".jpg" || file.Extension.ToLower() == ".png")
                                  orderby file.LastWriteTime
                                  select file;

foreach (System.IO.FileInfo fi in fileQuery)
{
    fi.Attributes = FileAttributes.Normal;
    FileList.Add(fi.FullName);
}
Calcareous answered 18/9, 2010 at 4:37 Comment(4)
file.Extension.ToLower() is bad practice.Toor
then what we should use? @ToorCumulate
@Nitin: String.Equals(a, b, StringComparison.OrdinalIgnoreCase)Toor
Actually, file.Extension.Equals(".jpg",StringComparison.OrdinalIgnoreCase) is what I prefer. It seems to be faster than .ToLower or .ToUpper, or so they say everywhere I searched. Actually, .Equals is faster than ==, as well, since == calls .Equals and checks for null(Because you cannot do null.Equals(null)).Handmaiden
E
5
DirectoryInfo directory = new DirectoryInfo(Server.MapPath("~/Contents/"));

//Using Union

FileInfo[] files = directory.GetFiles("*.xlsx")
                            .Union(directory
                            .GetFiles("*.csv"))
                            .ToArray();
Erroneous answered 19/4, 2013 at 9:40 Comment(1)
How can I look through files to get the path? ThanksGlace
D
5

in .NET 2.0 (no Linq):

public static List<string> GetFilez(string path, System.IO.SearchOption opt,  params string[] patterns)
{
    List<string> filez = new List<string>();
    foreach (string pattern in patterns)
    {
        filez.AddRange(
            System.IO.Directory.GetFiles(path, pattern, opt)
        );
    }


    // filez.Sort(); // Optional
    return filez; // Optional: .ToArray()
}

Then use it:

foreach (string fn in GetFilez(path
                             , System.IO.SearchOption.AllDirectories
                             , "*.xml", "*.xml.rels", "*.rels"))
{}
Daydream answered 3/9, 2014 at 11:31 Comment(0)
L
5

If you are using VB.NET (or imported the dependency into your C# project), there actually exists a convenience method that allows to filter for multiple extensions:

Microsoft.VisualBasic.FileIO.FileSystem.GetFiles("C:\\path", Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, new string[] {"*.mp3", "*.jpg"});

In VB.NET this can be accessed through the My-namespace:

My.Computer.FileSystem.GetFiles("C:\path", FileIO.SearchOption.SearchAllSubDirectories, {"*.mp3", "*.jpg"})

Unfortunately, these convenience methods don't support a lazily evaluated variant like Directory.EnumerateFiles() does.

Lahey answered 15/2, 2018 at 10:36 Comment(1)
This is easily the best answer and yet something much more hacky is the accepted one. Gotta love SO.Ondine
S
4

The following function searches on multiple patterns, separated by commas. You can also specify an exclusion, eg: "!web.config" will search for all files and exclude "web.config". Patterns can be mixed.

private string[] FindFiles(string directory, string filters, SearchOption searchOption)
{
    if (!Directory.Exists(directory)) return new string[] { };

    var include = (from filter in filters.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries) where !string.IsNullOrEmpty(filter.Trim()) select filter.Trim());
    var exclude = (from filter in include where filter.Contains(@"!") select filter);

    include = include.Except(exclude);

    if (include.Count() == 0) include = new string[] { "*" };

    var rxfilters = from filter in exclude select string.Format("^{0}$", filter.Replace("!", "").Replace(".", @"\.").Replace("*", ".*").Replace("?", "."));
    Regex regex = new Regex(string.Join("|", rxfilters.ToArray()));

    List<Thread> workers = new List<Thread>();
    List<string> files = new List<string>();

    foreach (string filter in include)
    {
        Thread worker = new Thread(
            new ThreadStart(
                delegate
                {
                    string[] allfiles = Directory.GetFiles(directory, filter, searchOption);
                    if (exclude.Count() > 0)
                    {
                        lock (files)
                            files.AddRange(allfiles.Where(p => !regex.Match(p).Success));
                    }
                    else
                    {
                        lock (files)
                            files.AddRange(allfiles);
                    }
                }
            ));

        workers.Add(worker);

        worker.Start();
    }

    foreach (Thread worker in workers)
    {
        worker.Join();
    }

    return files.ToArray();

}

Usage:

foreach (string file in FindFiles(@"D:\628.2.11", @"!*.config, !*.js", SearchOption.AllDirectories))
            {
                Console.WriteLine(file);
            }
Seringapatam answered 2/10, 2008 at 15:58 Comment(0)
O
4

What about

string[] filesPNG = Directory.GetFiles(path, "*.png");
string[] filesJPG = Directory.GetFiles(path, "*.jpg");
string[] filesJPEG = Directory.GetFiles(path, "*.jpeg");

int totalArraySizeAll = filesPNG.Length + filesJPG.Length + filesJPEG.Length;
List<string> filesAll = new List<string>(totalArraySizeAll);
filesAll.AddRange(filesPNG);
filesAll.AddRange(filesJPG);
filesAll.AddRange(filesJPEG);
Ouabain answered 21/5, 2015 at 18:10 Comment(0)
G
3

Just found an another way to do it. Still not one operation, but throwing it out to see what other people think about it.

private void getFiles(string path)
{
    foreach (string s in Array.FindAll(Directory.GetFiles(path, "*", SearchOption.AllDirectories), predicate_FileMatch))
    {
        Debug.Print(s);
    }
}

private bool predicate_FileMatch(string fileName)
{
    if (fileName.EndsWith(".mp3"))
        return true;
    if (fileName.EndsWith(".jpg"))
        return true;
    return false;
}
Groningen answered 2/10, 2008 at 17:17 Comment(0)
P
3

I wonder why there are so many "solutions" posted?

If my rookie-understanding on how GetFiles works is right, there are only two options and any of the solutions above can be brought down to these:

  1. GetFiles, then filter: Fast, but a memory killer due to storing overhead untill the filters are applied

  2. Filter while GetFiles: Slower the more filters are set, but low memory usage as no overhead is stored.
    This is explained in one of the above posts with an impressive benchmark: Each filter option causes a seperate GetFile-operation so the same part of the harddrive gets read several times.

In my opinion Option 1) is better, but using the SearchOption.AllDirectories on folders like C:\ would use huge amounts of memory.
Therefor i would just make a recursive sub-method that goes through all subfolders using option 1)

This should cause only 1 GetFiles-operation on each folder and therefor be fast (Option 1), but use only a small amount of memory as the filters are applied afters each subfolders' reading -> overhead is deleted after each subfolder.

Please correct me if I am wrong. I am as i said quite new to programming but want to gain deeper understanding of things to eventually become good at this :)

Phototypography answered 2/4, 2013 at 15:32 Comment(0)
L
3

Here is a simple and elegant way of getting filtered files

var allowedFileExtensions = ".csv,.txt";


var files = Directory.EnumerateFiles(@"C:\MyFolder", "*.*", SearchOption.TopDirectoryOnly)
                .Where(s => allowedFileExtensions.IndexOf(Path.GetExtension(s)) > -1).ToArray(); 
Leslielesly answered 12/6, 2020 at 10:50 Comment(1)
one issue with this code: if you have .xlsx in allowedFileExtensions, it will match .xlsx but also .xls and .xl and .xBevash
E
2

Nop... I believe you have to make as many calls as the file types you want.

I would create a function myself taking an array on strings with the extensions I need and then iterate on that array making all the necessary calls. That function would return a generic list of the files matching the extensions I'd sent.

Hope it helps.

Endocarditis answered 2/10, 2008 at 16:9 Comment(0)
I
2
/// <summary>
/// Returns the names of files in a specified directories that match the specified patterns using LINQ
/// </summary>
/// <param name="srcDirs">The directories to seach</param>
/// <param name="searchPatterns">the list of search patterns</param>
/// <param name="searchOption"></param>
/// <returns>The list of files that match the specified pattern</returns>
public static string[] GetFilesUsingLINQ(string[] srcDirs,
     string[] searchPatterns,
     SearchOption searchOption = SearchOption.AllDirectories)
{
    var r = from dir in srcDirs
            from searchPattern in searchPatterns
            from f in Directory.GetFiles(dir, searchPattern, searchOption)
            select f;

    return r.ToArray();
}
Institutional answered 15/12, 2011 at 7:27 Comment(0)
E
2

Make the extensions you want one string i.e ".mp3.jpg.wma.wmf" and then check if each file contains the extension you want. This works with .net 2.0 as it does not use LINQ.

string myExtensions=".jpg.mp3";

string[] files=System.IO.Directory.GetFiles("C:\myfolder");

foreach(string file in files)
{
   if(myExtensions.ToLower().contains(System.IO.Path.GetExtension(s).ToLower()))
   {
      //this file has passed, do something with this file

   }
}

The advantage with this approach is you can add or remove extensions without editing the code i.e to add png images, just write myExtensions=".jpg.mp3.png".

Evanne answered 2/4, 2012 at 22:24 Comment(1)
it doesn't know what is sProtactinium
T
2

I had the same problem and couldn't find the right solution so I wrote a function called GetFiles:

/// <summary>
/// Get all files with a specific extension
/// </summary>
/// <param name="extensionsToCompare">string list of all the extensions</param>
/// <param name="Location">string of the location</param>
/// <returns>array of all the files with the specific extensions</returns>
public string[] GetFiles(List<string> extensionsToCompare, string Location)
{
    List<string> files = new List<string>();
    foreach (string file in Directory.GetFiles(Location))
    {
        if (extensionsToCompare.Contains(file.Substring(file.IndexOf('.')+1).ToLower())) files.Add(file);
    }
    files.Sort();
    return files.ToArray();
}

This function will call Directory.Getfiles() only one time.

For example call the function like this:

string[] images = GetFiles(new List<string>{"jpg", "png", "gif"}, "imageFolder");

EDIT: To get one file with multiple extensions use this one:

/// <summary>
    /// Get the file with a specific name and extension
    /// </summary>
    /// <param name="filename">the name of the file to find</param>
    /// <param name="extensionsToCompare">string list of all the extensions</param>
    /// <param name="Location">string of the location</param>
    /// <returns>file with the requested filename</returns>
    public string GetFile( string filename, List<string> extensionsToCompare, string Location)
    {
        foreach (string file in Directory.GetFiles(Location))
        {
            if (extensionsToCompare.Contains(file.Substring(file.IndexOf('.') + 1).ToLower()) &&& file.Substring(Location.Length + 1, (file.IndexOf('.') - (Location.Length + 1))).ToLower() == filename) 
                return file;
        }
        return "";
    }

For example call the function like this:

string image = GetFile("imagename", new List<string>{"jpg", "png", "gif"}, "imageFolder");
Tolu answered 5/12, 2012 at 8:39 Comment(0)
C
2

Using GetFiles search pattern for filtering the extension is not safe!! For instance you have two file Test1.xls and Test2.xlsx and you want to filter out xls file using search pattern *.xls, but GetFiles return both Test1.xls and Test2.xlsx I was not aware of this and got error in production environment when some temporary files suddenly was handled as right files. Search pattern was *.txt and temp files was named *.txt20181028_100753898 So search pattern can not be trusted, you have to add extra check on filenames as well.

Cryostat answered 6/11, 2018 at 11:34 Comment(2)
Doesn't answer the question.Ondine
It says so in the Remark section - learn.microsoft.com/en-us/dotnet/api/…Declension
T
1

Or you can just convert the string of extensions to String^

vector <string>  extensions = { "*.mp4", "*.avi", "*.flv" };
for (int i = 0; i < extensions.size(); ++i)
{
     String^ ext = gcnew String(extensions[i].c_str());;
     String^ path = "C:\\Users\\Eric\\Videos";
     array<String^>^files = Directory::GetFiles(path,ext);
     Console::WriteLine(ext);
     cout << " " << (files->Length) << endl;
}
Tanana answered 8/4, 2014 at 20:51 Comment(1)
This is c++ not c#Protactinium
C
1

i don t know what solution is better, but i use this:

String[] ext = "*.ext1|*.ext2".Split('|');

            List<String> files = new List<String>();
            foreach (String tmp in ext)
            {
                files.AddRange(Directory.GetFiles(dir, tmp, SearchOption.AllDirectories));
            }
Cuddy answered 10/7, 2017 at 12:47 Comment(0)
E
0

you can add this to your project

public static class Collectables {
    public static List<System.IO.FileInfo> FilesViaPattern(this System.IO.DirectoryInfo fldr, string pattern) {
        var filter = pattern.Split(" ");
        return fldr.GetFiles( "*.*", System.IO.SearchOption.AllDirectories)
            .Where(l => filter.Any(k => l.Name.EndsWith(k))).ToList();
    }
}

then use it anywhere like this

new System.IO.DirectoryInfo("c:\\test").FilesViaPattern("txt doc any.extension");
Elbaelbart answered 4/6, 2022 at 5:34 Comment(0)
S
0

This is the shortest and performance wise the best solution:

            foreach (var FilePath in new[] { "*.fbx", "*.obj", "*.mtl" }.SelectMany(X => Directory.EnumerateFiles(DirectoryPath, X))) DoSomething(FilePath);
Sarsen answered 8/8, 2023 at 0:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.