I have read many threads on stackoverflow regarding the fastest way to delete a large number of files. What's the fastest way to delete a large folder in Windows? https://superuser.com/questions/19762/mass-deleting-files-in-windows/289399#289399 etc.
From my own testing, in C# code, the fastest way to delete files over the network seems to be invoking cmd.exe and using del /f/s/q
var before = DateTime.Now;
var cmd_line = "/c del /f/s/q \"" + Path.Combine(dir, num_to_delete.ToString()) + "\"";
var startInfo = new ProcessStartInfo("cmd", cmd_line)
{
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false
};
var process = new Process() { StartInfo = startInfo };
process.Start();
process.WaitForExit();
var stdOut = process.StandardOutput.ReadToEnd();
var stdErr = process.StandardError.ReadToEnd();
var complete = DateTime.Now;
My question is, is there a way to determine what del is doing under the hood? Is there an API in Win32 that I'm missing that I can call directly instead of spinning up a cmd.exe?
My code is in C#, but I wouldn't mind having to call something if this method isn't available from C#.
My testing methodology is as follows:
- create a folder with a number for the name (5, 10, 20, up to 10240)
- under 5, create a folder 1, put 1 100 KB file in it
- under 5, create a folder 2, put 2 100 KB files in it and so on until there are a total of 5 files under the leaf.
- then repeat the whole process for 10 and so on
this lets me create large amounts of files to dig through and delete a few of.
the first deletion method I tried was basically (this uses a structure like \5\1_0, 2_0 , 2_1) -- i.e. all the files in the same folder
string strFilePath = Path.Combine(dir, num_to_delete + "-*");
string strDirectory = Path.GetDirectoryName(strFilePath);
string strFileName = Path.GetFileName(strFilePath);
DateTime before, after, complete;
if (strDirectory != null && strFileName != null && Directory.Exists(strDirectory))
{
int number_present = Directory.GetFiles(strDirectory).Length;
before = DateTime.Now;
string[] strFiles = Directory.GetFiles(strDirectory, strFileName);
after = DateTime.Now;
foreach (string strFile in strFiles)
{
File.Delete(strFile);
}
complete = DateTime.Now;
}
the second deletion method uses the structure 5\1\, 5\2\, etc. string strDirectory = Path.Combine(dir, num_to_delete.ToString());
DateTime before, after, complete;
int number_present = Directory.GetFiles(dir).Length + Directory.GetDirectories(dir).Length;
before = DateTime.Now;
bool bExists = Directory.Exists(strDirectory);
after = DateTime.Now;
if(bExists)
{
Directory.Delete(strDirectory, true);
}
complete = DateTime.Now;
the third deletion method uses the same structure, but leaves the file behind: string strDirectory = Path.Combine(dir, num_to_delete.ToString()); string strFilePath = Path.Combine(strDirectory, "*"); string strFileName = Path.GetFileName(strFilePath);
DateTime before, after, complete;
if (Directory.Exists(strDirectory))
{
int number_present = Directory.GetFiles(strDirectory).Length;
before = DateTime.Now;
string[] strFiles = Directory.GetFiles(strDirectory, strFileName);
after = DateTime.Now;
foreach (string strFile in strFiles)
{
File.Delete(strFile);
}
complete = DateTime.Now;
The 4th is the one you see at the top.
My findings are that after 160 file sizes, deleting 5 files at a time in order of speed:
- 4th (del /f/s/q)
- 1st (delete the files from one big folder)
- 2nd (delete the files from a subfolder, but leave the folder)
- 3rd (delete the files from a subfolder and leave the subfolder)
I ran all the tests 3 times and averaged the results in excel and then charted it. I think I did my numerical analysis correctly.