After referring many blogs and articles, I have reached at the following code for searching for a string in all files inside a folder. It is working fine in my tests.
QUESTIONS
Note: I tested with very small files. Also very few number of files.
CODE
static void Main() { string sourceFolder = @"C:\Test"; string searchWord = ".class1"; List<string> allFiles = new List<string>(); AddFileNamesToList(sourceFolder, allFiles); foreach (string fileName in allFiles) { string contents = File.ReadAllText(fileName); if (contents.Contains(searchWord)) { Console.WriteLine(fileName); } } Console.WriteLine(" "); System.Console.ReadKey(); } public static void AddFileNamesToList(string sourceDir, List<string> allFiles) { string[] fileEntries = Directory.GetFiles(sourceDir); foreach (string fileName in fileEntries) { allFiles.Add(fileName); } //Recursion string[] subdirectoryEntries = Directory.GetDirectories(sourceDir); foreach (string item in subdirectoryEntries) { // Avoid "reparse points" if ((File.GetAttributes(item) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint) { AddFileNamesToList(item, allFiles); } } }
REFERENCE
To search multiple files with the grep command, insert the filenames you want to search, separated with a space character. The terminal prints the name of every file that contains the matching lines, and the actual lines that include the required string of characters. You can append as many filenames as needed.
Select Search > Find in Files from the menu. If you like keyboard shortcuts better, use Ctrl-Shift-F to open the search window instead. The find in files configuration window is pretty easy to use as you can ignore most options if you don't require them.
Search for a character in a string - strchr & strrchr The strchr function returns the first occurrence of a character within a string. The strrchr returns the last occurrence of a character within a string. They return a character pointer to the character found, or NULL pointer if the character is not found.
Instead of File.ReadAllText() better use
File.ReadLines(@"C:\file.txt");
It returns IEnumerable
(yielded) so you will not have to read the whole file if your string is found before the last line of the text file is reached
I wrote somthing very similar, a couple of changes I would recommend.
I was creating a binary search tool, here is some snippets of what I wrote to give you a hand
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { Parallel.ForEach(Directory.EnumerateFiles(_folder, _filter, SearchOption.AllDirectories), Search); } //_array contains the binary pattern I am searching for. private void Search(string filePath) { if (Contains(filePath, _array)) { //filePath points at a match. } } private static bool Contains(string path, byte[] search) { //I am doing ReadAllBytes due to the fact that I am doing a binary search not a text search // There are no "Lines" to seperate out on. var file = File.ReadAllBytes(path); var result = Parallel.For(0, file.Length - search.Length, (i, loopState) => { if (file[i] == search[0]) { byte[] localCache = new byte[search.Length]; Array.Copy(file, i, localCache, 0, search.Length); if (Enumerable.SequenceEqual(localCache, search)) loopState.Stop(); } }); return result.IsCompleted == false; }
This uses two nested parallel loops. This design is terribly inefficient, and could be greatly improved by using the Booyer-Moore search algorithm but I could not find a binary implementation and I did not have the time when I wrote it originally to implement it myself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With