SUMMARY
This step-by-step article shows through code how to
recursively search subdirectories for files, starting with a root directory. A
search string is specified so that you can search for files that match a
certain criteria. Each part of the code is explained as necessary. A working
code sample is also provided at the end of the article.
Directory
recursion is a common IO task for developers. The
FileSystemObject makes this task easy for Component Object Model (COM)
applications. Now this task has become even easier in .NET. Similar to the
FileSystemObject, the classes in the
System.IO namespace provide an object-oriented way to access files and
directories.
Requirements
- Microsoft Visual C# 2005 or Microsoft C# .NET
Directory recursion
The file and directory manipulation classes reside in the
System.IO namespace. Before you work with these classes, you should import
the following namespace into your project:
using System.IO;
The
System.IO namespace classes provide many options for working with files and
directories. The
System.IO namespace not only provides classes that you can instantiate, it
also provides file and directory utility classes. These classes contain static
methods that you can call without having to declare a variable of that type.
For example, you can use the
Directory object to obtain the subdirectories of a given
directory.
The following code uses the static
GetDirectoriesmethod of the
Directory object to return an array of strings. This array contains
directory path names to the subdirectories of the C directory, if any.
string[] directories = Directory.GetDirectories("C:\\");
The
Directory object also contains a method called
GetFiles that allows you to retrieve a string array of files that match a
certain criteria. The following code sample uses the
File object to retrieve all of the files in the C directory that end
with a .dll extension:
string[] files = Directory.GetFiles("C:\\", "*.dll");
The
GetDirectories and
GetFiles methods of the
Directory object are all that you need to recursively search for files that
match the search string. The following method is used to perform the recursion:
void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d, txtFile.Text))
{
lstFilesFound.Items.Add(f);
}
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
}
The preceding code passes a string, which contains the directory that
you want to search, to
DirSearch. This string value is the full path name of the directory. You
can use
GetDirectories to retrieve the subdirectories of the directory that is passed
into your procedure. Because
GetDirectories returns an array, you can use a for/each statement to iterate
over each subdirectory. For each subdirectory, use the
GetFiles method to iterate over the files in that directory. The value of
the text box on your form is passed to
GetFiles. The text box contains the search string that filters the results
that
GetFiles returns. If any files match the search criteria, they are added
to your list box. For each subdirectory that is located, call
DirSearch again, and pass it a subdirectory. By using this recursive call,
you can search all subdirectories of a given root directory.
Complete code sample
- Start a new Visual C# Windows Application project. Form1 is
created by default.
- From the View menu, click to display Solution Explorer.
- In Solution Explorer, right-click Form1, and then click View Code.
- In the Form1 code window, highlight and then delete all of
the existing code.
- Paste the following code in the code window of Form1:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
namespace RecursiveSearchCS
{
/// <summary>
/// Summary description for Form1
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
internal System.Windows.Forms.Button btnSearch;
internal System.Windows.Forms.TextBox txtFile;
internal System.Windows.Forms.Label lblFile;
internal System.Windows.Forms.Label lblDirectory;
internal System.Windows.Forms.ListBox lstFilesFound;
internal System.Windows.Forms.ComboBox cboDirectory;
/// <summary>
/// Required designer variable
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call.
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support: do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnSearch = new System.Windows.Forms.Button();
this.txtFile = new System.Windows.Forms.TextBox();
this.lblFile = new System.Windows.Forms.Label();
this.lblDirectory = new System.Windows.Forms.Label();
this.lstFilesFound = new System.Windows.Forms.ListBox();
this.cboDirectory = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// btnSearch
//
this.btnSearch.Location = new System.Drawing.Point(608, 248);
this.btnSearch.Name = "btnSearch";
this.btnSearch.TabIndex = 0;
this.btnSearch.Text = "Search";
this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click);
//
// txtFile
//
this.txtFile.Location = new System.Drawing.Point(8, 40);
this.txtFile.Name = "txtFile";
this.txtFile.Size = new System.Drawing.Size(120, 20);
this.txtFile.TabIndex = 4;
this.txtFile.Text = "*.dll";
//
// lblFile
//
this.lblFile.Location = new System.Drawing.Point(8, 16);
this.lblFile.Name = "lblFile";
this.lblFile.Size = new System.Drawing.Size(144, 16);
this.lblFile.TabIndex = 5;
this.lblFile.Text = "Search for files containing:";
//
// lblDirectory
//
this.lblDirectory.Location = new System.Drawing.Point(8, 96);
this.lblDirectory.Name = "lblDirectory";
this.lblDirectory.Size = new System.Drawing.Size(120, 23);
this.lblDirectory.TabIndex = 3;
this.lblDirectory.Text = "Look In:";
//
// lstFilesFound
//
this.lstFilesFound.Location = new System.Drawing.Point(152, 8);
this.lstFilesFound.Name = "lstFilesFound";
this.lstFilesFound.Size = new System.Drawing.Size(528, 225);
this.lstFilesFound.TabIndex = 1;
//
// cboDirectory
//
this.cboDirectory.DropDownWidth = 112;
this.cboDirectory.Location = new System.Drawing.Point(8, 128);
this.cboDirectory.Name = "cboDirectory";
this.cboDirectory.Size = new System.Drawing.Size(120, 21);
this.cboDirectory.TabIndex = 2;
this.cboDirectory.Text = "ComboBox1";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(688, 277);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.btnSearch,
this.txtFile,
this.lblFile,
this.lblDirectory,
this.lstFilesFound,
this.cboDirectory});
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void btnSearch_Click(object sender, System.EventArgs e)
{
lstFilesFound.Items.Clear();
txtFile.Enabled = false;
cboDirectory.Enabled = false;
btnSearch.Text = "Searching...";
this.Cursor = Cursors.WaitCursor;
Application.DoEvents();
DirSearch(cboDirectory.Text);
btnSearch.Text = "Search";
this.Cursor = Cursors.Default;
txtFile.Enabled = true;
cboDirectory.Enabled = true;
}
private void Form1_Load(object sender, System.EventArgs e)
{
cboDirectory.Items.Clear();
foreach (string s in Directory.GetLogicalDrives())
{
cboDirectory.Items.Add(s);
}
cboDirectory.Text = "C:\\";
}
void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d, txtFile.Text))
{
lstFilesFound.Items.Add(f);
}
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
}
}
}
Note
You must change the code in Visual Studio 2005. By default, Visual C# adds one form to the project when you create a Windows Forms project. The form is named Form1. The two files that represent the form are named Form1.cs and Form1.designer.cs. You write the code in the Form1.cs file. The Windows Forms Designer writes the code in the Form1.designer.cs file.
For more information about the Windows Forms Designer in Visual C# 2005, visit the following Microsoft Developer Network (MSDN) Web site: - Press F5 to build and then run the sample
program.