2

I'm looking for a way to improve my File Search.

Currently i'm working with this Method:

public IEnumerable<FileInfo> FindFilesInDirectory(string dirPath, string searchName)
{
    return Directory.Exists(dirPath)
               ? Directory.GetFiles(dirPath, "*.*", SearchOption.AllDirectories)
                          .ToList()
                          .ConvertAll(x => new FileInfo(x))
                          .Where(x => x.Name.ToLower().Contains(searchName.ToLower()))
               : null;
}

Is there any faster or better way to do this?

Thanks

5 Answers5

3

There's an overload that will search for a particular pattern. Instead of searching for *.* search for the filename you are interested in with the search pattern parameter.

Directory.GetFiles(dirPath, "*" + searchName + "*", SearchOption.AllDirectories);
Jeff Foster
  • 43,770
  • 11
  • 86
  • 103
  • 2
    `"*" + searchName` isn't quite the same as `x.Name.ToLower().Contains(searchName.ToLower())` and represents an endsWith search rather than a contains search. – spender Jul 02 '13 at 10:02
3

Nearly micro-optimization, however, you can improve readability and you could add exception handling.

You should also use EnumerateFiles(if possible) which does not need to load all into memory before it starts filtering. Also, use Equals with StringComparison.OrdinalIgnoreCase instead of ToLower since it's more efficient and less error-prone(the Turkey test).

public IEnumerable<FileInfo> FindFilesInDirectory(string dirPath, string searchName)
{
    if (Directory.Exists(dirPath))
    {
        var dir = new DirectoryInfo(dirPath);
        return dir.EnumerateFiles("*.*", SearchOption.AllDirectories)
                  .Where(fi => fi.Name.Equals(searchName, StringComparison.OrdinalIgnoreCase));
    }
    else
        throw new ArgumentException("Directory doesn't exist.", dirPath);
}
Community
  • 1
  • 1
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • My pleasure! Note that this really returns just an `IEnumerable`. So if you assign the return value to a variable you will always execute this query with methods that are not using deferred execution like `Enumerable.Count`. If you want to materialize this query you could add `ToList()`. For example: `List files = FindFilesInDirectory(@"D:\", "data.txt").ToList();`. But you can also enumerate it without creating a new collection if you use `foreach`. – Tim Schmelter Jul 02 '13 at 10:32
1
return Directory.Exists(dirPath)
           ? Directory.EnumerateFiles(
                dirPath, 
                string.Format("*{0}*",searchName), 
                SearchOption.AllDirectories)
              .Select(x => new FileInfo(x))
           : null;
spender
  • 117,338
  • 33
  • 229
  • 351
0
public IEnumerable<FileInfo> FindFilesInDirectory(string dirPath, string searchName)
{
    return Directory.Exists(dirPath)
               ? Directory.GetFiles(dirPath, "*" + searchName + "*", SearchOption.AllDirectories)
                          .Select(x => new FileInfo(x))
               : null;
}
Ahmed KRAIEM
  • 10,267
  • 4
  • 30
  • 33
0

I don't know what you're doing with your results, but I think it's worth mentioning that the execution of the query in your method will be deferred until you implement it. So depending on what you're doing with the query, it might slow down execution. If this wasn't intended, just add a .toList() to return a list for immediate execution.

Rei Mavronicolas
  • 1,387
  • 9
  • 12