/ Published in: C#
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.
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.
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
/// <summary> /// Get a list of files based on filename-with-wildcard search criteria and file-content search criteria. /// Regular expressions are not supported (yet). /// Calls System.IO.Directory.GetFiles to get files. /// Calls System.IO.File.ReadAllText().Contains to search contents. /// Uses ToLower() to perform case-insensitive search. /// </summary> /// <param name="directoryArg">Directory to start search, such as @"C:\" or Environment.GetEnvironmentVariable("SystemRoot")</param> /// <param name="containsTextArg">Test to search for. "" will be found in any file.</param> /// <param name="ignoreCaseArg"></param> /// <param name="searchSubDirsArg"></param> /// <param name="fileWildcardsArg">Can be an array of files or a single file such as "*.ini"</param> /// <returns>a list of files (complete paths) found.</returns> static IEnumerable<string> FindInFiles( string directoryArg, string containsTextArg, bool ignoreCaseArg, System.IO.SearchOption searchSubDirsArg, params string[] fileWildcardsArg ) { foreach (string fileWildcard in fileWildcardsArg ) { string[] xFiles = System.IO.Directory.GetFiles(directoryArg, fileWildcard, searchSubDirsArg); foreach ( string x in xFiles ) { if ( !files.Contains(x) ) // If file not already found... { // See if the file contains the search text. // Assume a null search string matches any file. // Use ToLower to perform a case-insensitive search. bool containsText = containsTextArg.Length==0 || ignoreCaseArg ? System.IO.File.ReadAllText(x).ToLower().Contains(containsTextArg.ToLower()) : System.IO.File.ReadAllText(x).Contains(containsTextArg); if ( containsText ) { files.Add(x); // This file is a keeper. Add it to the list. } // if } // if } // foreach file } foreach wildcard return files; } ///////////////////////////////////////// // LINQ-uified version of same function... ///////////////////////////////////////// static IEnumerable<string> FindInFiles( string directoryArg, string containsTextArg, bool ignoreCaseArg, System.IO.SearchOption searchSubDirsArg, params string[] fileWildcardsArg ) { IEnumerable<string> files = from fileWildcard in fileWildcardsArg from file in System.IO.Directory.GetFiles(directoryArg, fileWildcard, searchSubDirsArg) where containsTextArg.Length == 0 || ignoreCaseArg ? System.IO.File.ReadAllText(file).ToLower().Contains(containsTextArg.ToLower()) : System.IO.File.ReadAllText(file).Contains(containsTextArg) select file; return files; } /// LinqPad syntax for testing/debugging: var directoryArg = Environment.GetEnvironmentVariable("SystemRoot"); var searchSubDirsArg = System.IO.SearchOption.AllDirectories; var containsTextArg = "VID_08b1"; var ignoreCaseArg = true; IEnumerable<string> files = from fileWildcard in fileWildcardsArg from file in System.IO.Directory.GetFiles(directoryArg, fileWildcard, searchSubDirsArg) where containsTextArg.Length == 0 || ignoreCaseArg ? System.IO.File.ReadAllText(file).ToLower().Contains(containsTextArg.ToLower()) : System.IO.File.ReadAllText(file).Contains(containsTextArg) select file; files.Dump();