patterncsharpMinor
File text searcher
Viewed 0 times
textfilesearcher
Problem
I have a working version of a logfile searcher that targets a specific directory by extension type, and searches the files for certain words.
I'm wondering if my method is the most efficient implementation, or if there are things I could do better.
I'm wondering if my method is the most efficient implementation, or if there are things I could do better.
string startFolder = @"C:\logs\";
// search within these extensions
List searchExtensions = new List("log", "csv");
DirectoryInfo dir = new DirectoryInfo(startFolder);
// get files
IEnumerable fileList = dir.GetFiles("*.*", SearchOption.AllDirectories)
.Where(file => searchExtensions.Contains(file.Extension.Replace(".", "")));
// strings to search for
List lSearchTerms = new List() { "info", "error", "warning" };
// GetFileText simply returns the contents of the file
var queryMatchingFiles =
from file in fileList
let fileText = GetFileText(file.FullName)
where lSearchTerms.Any(val => fileText.Contains(val))
select file.FullName;Solution
List searchExtensions = new List("log", "csv");This doesn't need to be a
List - you're really only using it because it's an IEnumerable, so this would suffice:var searchExtensions = new[] { "log", "csv" };And when you're using it...
IEnumerable fileList = dir.GetFiles("*.*", SearchOption.AllDirectories)
.Where(file => searchExtensions.Contains(file.Extension.Replace(".", "")));You're calling
.Replace(".", "") to match your searchExtensions items... that replacement would be unnecessary if you had the dot in your extensions in the first place:var searchExtensions = new[] { ".log", ".csv" };
var files = dir.GetFiles("*.*", SearchOptions.AllDirectories)
.Where(file => searchExtensions.Contains(file.Extension));Side note, it's often preferable to use
string.Empty over "", to better communicate intent.The name
fileList is lying: it's an IEnumerable, not a List. Hence, files is a better, simpler name.List lSearchTerms = new List() { "info", "error", "warning" };I'm not sure why you've prefixed the
searchTerms with a lowercase "L", but again, you're declaring a List when all you need is an IEnumerable - again, a simple array would do:var searchTerms = new[] { "info", "warning", "error" };Listing the log levels you're interested in, in ascending order, makes the terms seem less arbitrarily chosen. If you're using NLog for logging,
Error isn't the highest log level available; are you missing "fatal"?Also
IEnumerable.Contains() is case-sensitive, which means if you're searching for info and your files contain Info or INFO, you're not getting all the results you indend to retrieve. More on this hereI'm not sure why the last instruction is using
var instead of explicitly declaring an IQueryable, but you should probably wrap the query in parentheses and call .ToList() and declare it as an IEnumerable instead.I might have a bias against the LINQ query syntax, but I have ran some tests, and this was slightly faster than the query syntax:
var searchResults = files.Where(file => terms.Any(term => File.ReadAllText(file.FullName).Contains(term)))
.Select(file => file.FullName);Side note about comments: there's too many of them. They are redundant and often only rephrase what the code is already saying; comments should say why, not what.
// filter doesn't support regex, so get all files *and then* filter by extension:
var files = dir.GetFiles("*.*", SearchOptions.AllDirectories)
.Where(file => searchExtensions.Contains(file.Extension));Code Snippets
List<string> searchExtensions = new List<string>("log", "csv");var searchExtensions = new[] { "log", "csv" };IEnumerable<FileInfo> fileList = dir.GetFiles("*.*", SearchOption.AllDirectories)
.Where(file => searchExtensions.Contains(file.Extension.Replace(".", "")));var searchExtensions = new[] { ".log", ".csv" };
var files = dir.GetFiles("*.*", SearchOptions.AllDirectories)
.Where(file => searchExtensions.Contains(file.Extension));List<string> lSearchTerms = new List<string>() { "info", "error", "warning" };Context
StackExchange Code Review Q#54036, answer score: 7
Revisions (0)
No revisions yet.