-4

I have two folders : FolderA and FolderB I want to delete the files in FolderA which also exist in FolderB. (i.e. Common files will be deleted from folderA)

How can I do this most efficiently in C#? (That's a critical point in the project and it has to be as efficient as possible )

Thanx

EngelbertCoder
  • 777
  • 2
  • 9
  • 29

5 Answers5

2

You can do this with the help of LINQ. See here.

d.moncada
  • 16,900
  • 5
  • 53
  • 82
2

This is easy, readable and also efficient:

var common = from f1 in Directory.EnumerateFiles(folderA, "*.*", SearchOption.AllDirectories)
             join f2 in Directory.EnumerateFiles(folderB, "*.*", SearchOption.AllDirectories)
             on Path.GetFileName(f1) equals Path.GetFileName(f2)
             select f1;

foreach (string file in common)
{
    File.Delete(file);
}

Assuming that you just want to compare the file names (and extension).

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • I am not so familiar with that syntax but it looks very compact. How can we extend it efficiently so that to delete both of the files(both on f1 and f2)? – EngelbertCoder Dec 19 '12 at 09:24
  • @EngelbertCoder: Then you need to use an anonymous type. Here's the code-difference: `select new { File1 = f1, File2 = f2 }; foreach (var files in common) { File.Delete(files.File1); File.Delete(files.File2); }`. Btw, that's the Linq query syntax. You could also use the [method syntax](http://msdn.microsoft.com/en-us/library/system.linq.enumerable.join.aspx) but i prefer queries with `Joins`. – Tim Schmelter Dec 19 '12 at 09:31
  • @EngelbertCoder: [**Here**](http://stackoverflow.com/questions/5551264/why-is-linq-join-so-much-faster-than-linking-with-where) are some infos on `Join` and it's performance. – Tim Schmelter Dec 19 '12 at 09:38
2

If you only want to compare file names, here is how you can do it, I did a quick test of this code and it works:

        string pathA = @"C:\New FolderA";
        string pathB = @"C:\New FolderB";

        var filesA = Directory.GetFiles(pathA).Select(path => Path.GetFileName(path));
        var filesB = Directory.GetFiles(pathB).Select(path => Path.GetFileName(path));

        var toBeDeleted = filesA.Intersect(filesB);
        foreach (string filename in toBeDeleted)
            File.Delete(Path.Combine(pathA, filename));
Ivan Golović
  • 8,732
  • 3
  • 25
  • 31
  • 2
    This answer has three disadvantages. 1. Doesn't work if he wants to search sub-directories(`SearchOption.AllDirectories`) since you're combining with the root directory. 2. Needs to load all into memory first unlike the `EnumerateFiles` methods 3. Is less extensible if OP also wants to include the file-size or other properties. – Tim Schmelter Dec 19 '12 at 09:13
  • 1
    OP said he needed to compare file names only. If he's working with .NET version lower than 4, he can't use `EnumerateFiles`. – Ivan Golović Dec 19 '12 at 09:21
0
 string[] FolderAFiles = Directory.GetFiles(@"Path");
            string[] FolderBFiles = Directory.GetFiles(@"BPath");
            foreach (string Files in FolderAFiles)
            {
                if (FolderBFiles.Contains(Files))
                {
                    File.Delete(Files);
                }
            }

Try this

User2012384
  • 4,769
  • 16
  • 70
  • 106
0

Here's one another solution.

var filesInB = System.IO.Directory.GetFiles("FolderB");
Array.ForEach(System.IO.Directory.GetFiles("FolderA"), delegate(string fileName){
    if (filesInB.Contains(fileName)) System.IO.File.Delete(fileName);
});
sohail.hussain.dyn
  • 1,411
  • 1
  • 16
  • 26