views:

3629

answers:

8

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?

+3  A: 

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

Chris Lively
A: 

nop... I believe you have to make as many calls a file types you want. I would create a function myself taking an array on strings (string[]) 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

sebastian
+15  A: 
var files = Directory.GetFiles("C:\\path", "*.*", SearchOption.AllDirectories)
            .Where(s => s.EndsWith(".mp3") || s.EndsWith(".jpg"));
Lette
Man, I have to think in terms of LINQ more often. Nice solution!
Ken Pespisa
Simply awesome.
flavour404
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.
Christian.K
... 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...`
Stormenet
you could just use `s.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)`
Paul Farry
+1  A: 

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;
}
Jason Z
+1  A: 

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);
            }
Alexander Popov
A: 
Directory.GetFiles(path, SearchOption.AllDirectories)
    .Where(f => new[] { ".mp3", ".jpg" })
        .Contains(new FileInfo(f).Extension));
abatishchev
A: 
            DirectoryInfo di = null;
            List<string> FileList = new List<string>();
            di = new DirectoryInfo(@"C:\DirName\");


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

            //Create the query
            IEnumerable<System.IO.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);
            }
Rajeesh Kuthuparakkal
A: 

and with no Linq?!!

peace