FindInFiles, C# static function


/ Published in: C#
Save to your folder(s)

This function provides C# with functionality similar to the apparently deprecated my.Computer.FileSystem.FindInFiles under the Microsoft.VisualBasic namespace.

Example usage:
IEnumerable oemFiles = FindInFiles(
Environment.GetEnvironmentVariable("SystemRoot"),
"VID_08b1",
false,
System.IO.SearchOption.AllDirectories,
"OEM*.INF"
);

There are two implementations in Source: [1] foreach and [2] LINQ-uified. The foreach version has nested foreach loops: one for the fileWildcards and one to search the contents of the files. There's an if statement that prevents duplicates. The LINQ-uified version is also nested - it has nested from clauses.

The LINQ-uified version is definitely more concise. It's harder to debug - can't really be stepped-through. This seems to be the classic trade-off between the imperative foreach approach and the functional LINQ approach.

Source also contains LinqPad syntax. LinqPad can be downloaded at http://www.linqpad.net/. It'll translate from LINQ to Lambda but I think Lambda is harder to read.


Copy this code and paste it in your HTML
  1. /// <summary>
  2. /// Get a list of files based on filename-with-wildcard search criteria and file-content search criteria.
  3. /// Regular expressions are not supported (yet).
  4. /// Calls System.IO.Directory.GetFiles to get files.
  5. /// Calls System.IO.File.ReadAllText().Contains to search contents.
  6. /// Uses ToLower() to perform case-insensitive search.
  7. /// </summary>
  8. /// <param name="directoryArg">Directory to start search, such as @"C:\" or Environment.GetEnvironmentVariable("SystemRoot")</param>
  9. /// <param name="containsTextArg">Test to search for. "" will be found in any file.</param>
  10. /// <param name="ignoreCaseArg"></param>
  11. /// <param name="searchSubDirsArg"></param>
  12. /// <param name="fileWildcardsArg">Can be an array of files or a single file such as "*.ini"</param>
  13. /// <returns>a list of files (complete paths) found.</returns>
  14. static IEnumerable<string> FindInFiles(
  15. string directoryArg,
  16. string containsTextArg,
  17. bool ignoreCaseArg,
  18. System.IO.SearchOption searchSubDirsArg,
  19. params string[] fileWildcardsArg )
  20. {
  21. List<String> files = new List<string>(); // This List accumulates files found.
  22.  
  23. foreach (string fileWildcard in fileWildcardsArg )
  24. {
  25. string[] xFiles = System.IO.Directory.GetFiles(directoryArg, fileWildcard, searchSubDirsArg);
  26.  
  27. foreach ( string x in xFiles )
  28. {
  29. if ( !files.Contains(x) ) // If file not already found...
  30. {
  31. // See if the file contains the search text.
  32. // Assume a null search string matches any file.
  33. // Use ToLower to perform a case-insensitive search.
  34. bool containsText =
  35. containsTextArg.Length==0 ||
  36. ignoreCaseArg ?
  37. System.IO.File.ReadAllText(x).ToLower().Contains(containsTextArg.ToLower()) :
  38. System.IO.File.ReadAllText(x).Contains(containsTextArg);
  39.  
  40. if ( containsText )
  41. {
  42. files.Add(x); // This file is a keeper. Add it to the list.
  43. } // if
  44. } // if
  45. } // foreach file
  46. } foreach wildcard
  47. return files;
  48. }
  49.  
  50. /////////////////////////////////////////
  51. // LINQ-uified version of same function...
  52. /////////////////////////////////////////
  53. static IEnumerable<string> FindInFiles(
  54. string directoryArg,
  55. string containsTextArg,
  56. bool ignoreCaseArg,
  57. System.IO.SearchOption searchSubDirsArg,
  58. params string[] fileWildcardsArg )
  59. {
  60.  
  61. IEnumerable<string> files =
  62. from fileWildcard in fileWildcardsArg
  63. from file in System.IO.Directory.GetFiles(directoryArg, fileWildcard, searchSubDirsArg)
  64. where
  65. containsTextArg.Length == 0 ||
  66. ignoreCaseArg ?
  67. System.IO.File.ReadAllText(file).ToLower().Contains(containsTextArg.ToLower()) :
  68. System.IO.File.ReadAllText(file).Contains(containsTextArg)
  69. select file;
  70.  
  71. return files;
  72. }
  73.  
  74.  
  75. /// LinqPad syntax for testing/debugging:
  76. var fileWildcardsArg = new[] { "OEM*.inf" }.AsQueryable();
  77. var directoryArg = Environment.GetEnvironmentVariable("SystemRoot");
  78. var searchSubDirsArg = System.IO.SearchOption.AllDirectories;
  79. var containsTextArg = "VID_08b1";
  80. var ignoreCaseArg = true;
  81.  
  82. IEnumerable<string> files =
  83. from fileWildcard in fileWildcardsArg
  84. from file in System.IO.Directory.GetFiles(directoryArg, fileWildcard, searchSubDirsArg)
  85. where
  86. containsTextArg.Length == 0 ||
  87. ignoreCaseArg ?
  88. System.IO.File.ReadAllText(file).ToLower().Contains(containsTextArg.ToLower()) :
  89. System.IO.File.ReadAllText(file).Contains(containsTextArg)
  90. select file;
  91.  
  92. files.Dump();

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.