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#