Is there a better way to search directories for a file or files?

Edit:

The purpose of this method is to search a specific directory for a given file type, ex. (*.txt, *.pdb, *.exe") then move the file(s) to a given destination directory and delete the original file from the source directory.

Is there a better way to write the following code?:

/// <summary>
/// Moves a specific file type from a given
/// source directory to a destination directory.
/// </summary>
/// <param name="sourceDir">The source directory.</param>
/// <param name="destDir">The destination directory.</param>
/// <param name="fileExt">Type of file to be moved.</param>
private static void MoveFilesToDirectory(string sourceDir, string destDir, string fileExt)
{
try
{
if ( !Directory.Exists(sourceDir) )
{
Console.WriteLine("{0} does not exist.", sourceDir);
return;
}

if ( !Directory.Exists(destDir) )
{
Directory.CreateDirectory(destDir);
}

foreach ( String dir in Directory.GetDirectories(sourceDir) )
{
foreach ( String file in Directory.GetFiles(dir, fileExt) )
{
string fileName = Path.GetFileName(file);
string moveFileTo = Path.Combine(destDir, fileName);

if ( !File.Exists(moveFileTo) )
{
Directory.Move(file, moveFileTo);
}

File.Delete(file);
}

MoveFilesToDirectory(dir, destDir, fileExt);
}
}
catch ( IOException ex )
{
Console.WriteLine(ex.Message);
}
}

• Your code does something else than the title indicates? Apr 26 '11 at 11:02
• How so? Look at my edit please. Apr 26 '11 at 11:29
• Is the RemoveFilesFromDirectory call actually meant to be a recursive call to MoveFilesToDirectory? Apr 26 '11 at 12:10

    static void Main(string[] args)
{
String source = @"c:\source\";
String destination = @"c:\destination\";

String[] files = Directory.GetFiles(source, mask, SearchOption.AllDirectories);
foreach (String file in files)
{
File.Move(file, destination + new FileInfo(file).Name);
}
}


Add in your own directory exists verification logic... but this should be all you need at the core. I haven't verified this code, but these built in functions should do what you want.

• @schlechtums: Thanks! A buddy of mine just helped me come up with the same solution. I didn't know about the SearchOption.AllDirectories enum. Apr 26 '11 at 13:21
• FYI: .NET 4 introduced a new method called Directory.EnumerateFiles. From MSDN: "The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names before the whole collection is returned; when you use GetFiles, you must wait for the whole array of names to be returned before you can access the array. Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient." Apr 26 '11 at 15:46
• @Adam Spicer: does enumerate work if you delete a file from the source directory you are enumerating over? With Directory.GetFiles() you first get all source filenames and then delete some of them.
– k3b
Apr 26 '11 at 19:34
• @k3b I haven't researched your question. It would be an interesting test to perform as deleting from enumeration doesn't usually work because it modifies the collection. But since deleting the file isn't removing something from a collection it probably will be ok. Apr 28 '11 at 2:21
• always use Path.Combine(path1, path2) to avoid "/" and get valid IO path May 2 '11 at 14:29

From msdn:

string sourceFile = @"C:\Users\Public\public\test.txt";
string destinationFile = @"C:\Users\Public\private\test.txt";

// To move a file or folder to a new location:
System.IO.File.Move(sourceFile, destinationFile);

// To move an entire directory. To programmatically modify or combine
// path strings, use the System.IO.Path class.
System.IO.Directory.Move(@"C:\Users\Public\public\test\", @"C:\Users\Public\private");

• That doesn't have the file searching capability that I have in my above method. Apr 26 '11 at 11:31