Compare directories to see which files they have in common in C#

This example compares directories to see which files they have in common and which files are only in one directory. When you click the Compare button, the following code executes.

// Compare the files in each directory.
private void btnCompare_Click(object sender, EventArgs e)
{
    // Clear previous results.
    dgvFiles.Rows.Clear();

    // Get sorted lists of files in the directories.
    string dir1 = txtDir1.Text;
    if (!dir1.EndsWith("\\")) dir1 += "\\";
    string[] file_names1 = Directory.GetFiles(dir1);
    for (int i = 0; i < file_names1.Length; i++)
    {
        file_names1[i] = file_names1[i].Replace(dir1, "");
    }
    Array.Sort(file_names1);

    string dir2 = txtDir2.Text;
    if (!dir2.EndsWith("\\")) dir2 += "\\";
    string[] file_names2 = Directory.GetFiles(dir2);
    for (int i = 0; i < file_names2.Length; i++)
    {
        file_names2[i] = file_names2[i].Replace(dir2, "");
    }
    Array.Sort(file_names2);

    // Compare.
    int i1 = 0, i2 = 0;
    while ((i1 < file_names1.Length) && (i2 < file_names2.Length))
    {
        if (file_names1[i1] == file_names2[i2])
        {
            // They match. Display them both.
            dgvFiles.Rows.Add(new Object[] { file_names1[i1], file_names2[i2] });
            i1++;
            i2++;
        }
        else if (file_names1[i1].CompareTo(file_names2[i2]) < 0)
        {
            // Display the directory 1 file.
            dgvFiles.Rows.Add(new Object[] { file_names1[i1], null });
            i1++;
        }
        else
        {
            // Display the directory 2 file.
            dgvFiles.Rows.Add(new Object[] { null, file_names2[i2] });
            i2++;
        }
    }

    // Display remaining directory 1 files.
    for (int i = i1; i < file_names1.Length; i++)
    {
        dgvFiles.Rows.Add(new Object[] { file_names1[i], null });
    }

    // Display remaining directory 2 files.
    for (int i = i2; i < file_names2.Length; i++)
    {
        dgvFiles.Rows.Add(new Object[] { null, file_names2[i] });
    }
}

The code first clears any previous results from its DataGridView control. It then uses the Directories.GetFiles method to get the names of the files in the first directory. It removes the directory name form the file names and uses Array.Sort to sort the names.

The code repeats these steps to get the names of the files in the second directory and sort them.

Next the code loops through the arrays comparing their entries. If two entries match, the code adds them both to the program’s DataGridView control. If the files don’t match, the program adds the one that comes alphabetically first to the DataGridView and increments its array’s counter.

When one of the arrays runs out of entries, the program dumps any remaining names in the other array into the DataGridView.






This entry was posted in directories, files and tagged , , , , , , , , , , , . Bookmark the permalink.

5 Responses to Compare directories to see which files they have in common in C#

  1. kuru says:

    Good article? But in my mind use LINQ is much easyer and much readable.

    //files just in directory 1
    var fileJustInDir1 = from f1 in file_names1
       where !(from f2 in file_names2
           select f2).Contains (f1)
       select f1;
    
    foreach (var f in fileJustInDir1 )
    {
        dgvFiles.Rows.Add(new object[] {f,null });
    }
  2. Rod Stephens says:

    I think as it is written this doesn’t quite work. I suspect it’s because the file names include the complete path. Since we’re comparing two different directories, they will always have different paths. Directory.GetFiles only returns file titles (names without the path).

    But I agree that something like this might be simpler to code in LINQ. You could select both the file’s title and path. Or perhaps title and a FileInfo object.

    I also wonder how smart LINQ is about this sort of query. It would slow things down, for example, if it selected all files in directory 2 for each file in directory 1.

    When I have time, I may write an example to compare the two approaches.

  3. Pingback: Test methods that compare directories in C#

  4. Ello says:
    var filesWithTheSameName =
        from files1 in Directory.GetFiles(textBox1.Text)
        from files2 in Directory.GetFiles(textBox2.Text)
        let files1Info = new FileInfo(files1)
        let files2Info = new FileInfo(files2)
        where files1Info.Name == files2Info.Name
        select new { files1Info, files2Info };
    
    foreach (var files in filesWithTheSameName)
    {
        dataGridView1.Rows.Add(new object[]
            { files.files1Info.Name, files.files2Info.Name });
    }

Leave a Reply

Your email address will not be published. Required fields are marked *