Read/Write action vs ReadAll/WriteAll

Recently I needed to go over a lot of files located inside a directory and its subfolders. This is a fairly easy something to implement and without much thinking I wrote some code to loop through the directory, compare the files found with a criteria and if it matched, copy the file.

Afterwards I was wondering if there maybe was a faster way of doing this Read/Write action I was doing.
Another option was loop through the folders comparing and remembering the files I needed to copy. Then at the end loop through the matching files and copy them.
What the test showed was a ReadAll / WriteAll action is notably faster, especially if the number if matches is low.

Test results

I took a directory with 87 subfolders and a total of 686 files in them. Total size of 3.13 GB, making the average filesize 4.6MB.
The test was run twice. Once with the criteria matching 19 items, once with it matching 435 items.

  Read/Write ReadAll/WriteAll Speedgain
19 matches 3499 milliseconds 1437 milliseconds 58.9%
435 matches 94326 milliseconds 86748 milliseconds 8%

The code


class Program
{
static List paths = new List();

static void Main(string[] args)
{
string pathtoexamine = @"D:MusiciTunes";
string targetpath = @"D:MusiciTunesCopy";

DateTime starttime = DateTime.Now;
WriteAfterRead(pathtoexamine, targetpath);
Console.WriteLine(DateTime.Now.Subtract(starttime).TotalMilliseconds);
// Clear directory between tests.
DateTime starttime2 = DateTime.Now;
ReadAllToList(pathtoexamine);
WriteAllFromList(targetpath);
Console.WriteLine(DateTime.Now.Subtract(starttime2).TotalMilliseconds);
Console.ReadLine();
}

private static void WriteAfterRead(string frompath, string targetpath)
{
Console.WriteLine(frompath);
string[] files = Directory.GetFiles(frompath);
foreach (string file in files)
{
string filename = Path.GetFileName(file);
if (NeedsAction(filename))
{
Console.Write("*");
File.Copy(file, targetpath + Path.DirectorySeparatorChar + filename, true);
}
}
string[] directories = Directory.GetDirectories(frompath);
foreach (string directory in directories)
{
WriteAfterRead(directory, targetpath);
}
}

private static void ReadAllToList(string frompath)
{
Console.WriteLine(frompath);
string[] files = Directory.GetFiles(frompath);
foreach (string file in files)
{
string filename = Path.GetFileName(file);
if (NeedsAction(filename))
{
paths.Add(file);
}
}
string[] directories = Directory.GetDirectories(frompath);
foreach (string directory in directories)
{
ReadAllToList(directory);
}
}

private static void WriteAllFromList(string targetpath)
{
foreach (string filepath in paths)
{
Console.Write("*");
string filename = Path.GetFileName(filepath);
File.Copy(filepath, targetpath + Path.DirectorySeparatorChar + filename, true);
}
}

public static bool NeedsAction(string filename)
{
bool result = false;
if ((filename != null) && filename.ToLower().Contains("0"))
{
result = true;
}
return result;
}
}