Monday, October 13, 2008

C# Tutorial - A Simple File Search Utilities

The search tool in Microsoft Windows is a nice tool, but I find that it has limitations. For example, if I'm searching for files that contain a word or a phrase, it doesn't necessarily display all the files containing that word or phrase, especially if the file type is a script or a program.


Click the link to download the source code for this post

Licensing and Warranty

You may use the code as you wish - it may be used in commercial or other applications, and it may be redistributed and modified. The code is provided "as-is". No claim of suitability, guarantee, or any warranty whatsoever is provided. By downloading the code, you agree to defend, indemnify, and hold harmless the Author and the Publisher from and against any claims, suits, losses, damages, liabilities, costs, and expenses (including reasonable legal or attorneys' fees) resulting from or relating to any use of the code by you.




While I was practicing my C# skills, I wrote a simple search utility (using Visual Studio 2003) a few years ago that will search through all files for a word or phrase. This little program also gave me some practice with the System.IO functions.

How It Works
Basically, the user enters a directory to search through (either a mapped directory {drive letter} or a network share) and enters the word or phrase to search for. When the user clicks search, the program does the following:

  • It uses the function System.IO.Directory.Exists to check whether the directory exists

  • If the directory exists, it uses the DirectoryInfo class to capture the directory information, and then uses the FileInfo class to capture the list of files that exist in the directory.

  • Using a for loop, it loops through the list of files. During each iteration of the loop, it opens each file and uses another for loop to read through the contents of the file. During each iteration of the loop, it uses the IndexOffunction to check whether the phrase is in the file. If it's found (IndexOf > -1), write the name of the file in the results box. (For efficiency, break out of the loop and go to the next file).


Here is the code snippet of the process:

if (System.IO.Directory.Exists(txtDirectory.Text))
{
   txtResults.Text = "";
   DirectoryInfo dir = new DirectoryInfo(txtDirectory.Text);
   FileInfo[] fileList = dir.GetFiles();
   FileInfo currFile;
   StreamReader s;
   string fileToOpen;
   bool hasPhrase = false;

   for (int x = 0; x < fileList.Length; x++)
   {
     //Open the file
     currFile = fileList[x];
     fileToOpen = dir.ToString() + "\\" + currFile.ToString();
     s = File.OpenText(fileToOpen);

     // Find the text pattern in the file
     string read = null;
     while ((read = s.ReadLine()) != null)
     {
       if (read.IndexOf(txtPhrase.Text) > -1)
       {
       hasPhrase = true;
       break;
     }
   }

   // If the text pattern is in the file, write the file name in the output
   if (hasPhrase)
   {
     txtResults.Text += currFile.Name;
     txtResults.Text += "\r\n";
   }

   currFile = null;
   s.Close();
   s = null;
   hasPhrase = false;

}


If you want to look at the code and/or use it as a foundation for your project, click on the link at the beginning of this post. {I recreated the code in Visual Studio 2005.} Note that this program is just a simple example; it is not robust! For more practice, here are some suggested changes to make to the original code:

  • Change the code to allow it to traverse through subdirectories

  • Change the code to handle wildcards

  • Add good error handling (try-catch loops) to the code

  • Allow the user to open the file by clicking on the file name in the results list

  • Allow the user to click "browse" and select a directory from a list.

  • Enhance the look and feel

  • Refactor some of the code for better performance (ex: use a StringBuffer where appropriate)

1 comment:

Jennifer said...

Here are a few tips for the code to "pepper it up", so to speak:
- Rather than using the indexOf() function to determine whether the text is in the file, you can also use the contains() function to check the string value.
- Rather than reading the file line by line, you can read the contents into a buffer array, convert the buffer array contents into a string, and then either use the contains() or the indexOf() functions to find the string value.