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

Posted by umer on Fri, 06 Mar 2020 11:56:12 +0100

I'm trying to use the Directory.GetFiles() method to retrieve a list of multiple types of files, such as mp3 and jpg. Without luck, I tried the following two methods:

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

Is there a way to do this on a phone?

#1 building

I know it's an old problem, but LINQ: (. NET40 +)

var files = Directory.GetFiles("path_to_files").Where(file => Regex.IsMatch(file, @"^.+\.(wav|mp3|txt)$"));

#2 building

I ran into 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 only call Directory.Getfiles().

For example, call the following function:

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

Edit: to get a file with multiple extensions, use this file:

/// <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 following function:

string image = GetFile("imagename", new List<string>{"jpg", "png", "gif"}, "imageFolder");

#3 building

There is also a declining solution that seems to have no memory or performance overhead and is elegant:

string[] filters = new[]{"*.jpg", "*.png", "*.gif"};
string[] filePaths = filters.SelectMany(f => Directory.GetFiles(basePath, f)).ToArray();

#4 building

I don't know why so many "solutions" have been released?

If my new understanding of how GetFiles works is correct, there are only two options, and any of the above solutions can be summed up as follows:

  1. GetFiles, then filter: fast, but because of storage overhead, it didn't become a memory killer until the filter was applied

  2. Filter on GetFiles: the slower the filter is set, but the memory usage is low due to no storage overhead.
    This is illustrated in an impressive benchmark in the previous article: each filter option results in a separate GetFile operation, so the same part of the hard disk will be read multiple times.

I think option 1) is better, but using SearchOption.AllDirectories on folders such as C: \ \, will take up a lot of memory.
Therefore, I will only use option 1 to develop a recursive sub method that traverses all subfolders

This should result in only one GetFiles operation per folder, so it is faster (option 1), but only uses a small amount of memory, because the filter - > delete after each subfolder is read is overhead.

If I am wrong, please correct me. As I said, I'm strange to programming, but I want to have a deeper understanding of things, and finally I'm good at it:)

#5 building

DirectoryInfo directory = new DirectoryInfo(Server.MapPath("~/Contents/"));

//Using Union

FileInfo[] files = directory.GetFiles("*.xlsx")
                            .Union(directory
                            .GetFiles("*.csv"))
                            .ToArray();

Topics: Programming