dragon123
dragon123

Reputation: 303

File access in C#

Directory levels I have directories arranged as in the picture. I want to edit the files OneA1, OneA2,OneA3.. and TwoA1, TwoA2, TwoA3... (They are xml files and want to edit some tags). There are 100s of files in C drive. How do I filter the required files in C# ? Aim is to filter all xml files with file names contain the word OneA and OneB.

static void Main (string[] args)
{
    DirectoryInfo directory = new DirectoryInfo (@"C:\Products\MetalicProducts");
}

Upvotes: 0

Views: 81

Answers (1)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112437

You can use a search option to include all subdirectories:

var prefilteredFiles = Directory.EnumerateFiles(path, "???A*.xml",
    SearchOption.AllDirectories);
var filtered = prefilteredFiles 
   .Select(f => (full: f, name: Path.GetFileNameWithoutExtension(f)))
   .Where(t => t.name.StartsWith("OneA") || t.name.StartsWith("TwoA"));

The wildcard pattern ???A*.xml pre-filters the files but is not selective enough. Therefore we use LINQ to refine the search.

The Select creates a tuple with the full file name including the directory and the extension and the bare file name.

Of course you could use Regex if the simple string operations are not precise enough:

var filtered = prefilteredFiles 
    .Where(f => 
        Regex.IsMatch(Path.GetFileNameWithoutExtension(f), "(OneA|TwoA)[1-9]+")
    );

This also has the advantage that only one test per file is required what allows us to discard the Select.

You also might use a pre-compiled regex to speed up the search; however, file operations are usually very slow compared to any calculations.

Note that DirectoryInfo also has a EnumerateFiles method with a SearchOption parameter. It will return FileInfo objects instead of just file names.

Upvotes: 1

Related Questions