Revision: 9886
Updated Code
at November 28, 2008 20:09 by jimfred
Updated Code
/// <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 ) { List<String> files = new List<string>(); // This List accumulates files found. 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 fileWildcardsArg = new[] { "OEM*.inf" }.AsQueryable(); 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();
Revision: 9885
Updated Code
at November 28, 2008 18:32 by jimfred
Updated Code
/// <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 ) { List<String> files = new List<string>(); // This List accumulates files found. 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; }
Revision: 9884
Updated Code
at November 28, 2008 16:50 by jimfred
Updated Code
/// <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 ) { List<String> files = new List<string>(); // This List accumulates files found. 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-ified 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; }
Revision: 9883
Updated Code
at November 28, 2008 03:03 by jimfred
Updated Code
/// <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 ) { List<String> files = new List<string>(); // This List accumulates files found. 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; }
Revision: 9882
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at November 28, 2008 02:59 by jimfred
Initial Code
/// <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 ) { List<String> files = new List<string>(); // This List accumulates files found. foreach (string fileWildcard in fileWildcardsArg ) { string[] xFiles = System.IO.Directory.GetFiles(directoryArg, fileWildcard, searchSubDirsArg); foreach ( string x in xFiles ) { if ( !files.Contains(x) ) { 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); } } } } return files; }
Initial URL
Initial Description
This function provides C# with functionality similar to the apparently deprecated my.Computer.FileSystem.FindInFiles under the Microsoft.VisualBasic namespace. Example usage: IEnumerable<string> 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.
Initial Title
FindInFiles, C# static function
Initial Tags
c
Initial Language
C#