Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble comparing two directories

Tags:

c#

I am trying to compare two directories to see what files are in directory 1 that are not in directory 2. I have the following code:

System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(pathA);
System.IO.DirectoryInfo dir2 = new System.IO.DirectoryInfo(pathB);

IEnumerable<System.IO.FileInfo> list1 = dir1.GetFiles("*.PRN");
IEnumerable<System.IO.FileInfo> list2 = dir2.GetFiles("*.PRN");

IEnumerable<System.IO.FileInfo> list3 = list1.Except(list2);

Console.WriteLine("The following files are in list1 but not list2:");

foreach (var v in list3)
{
    Console.WriteLine(v);
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();

When this runs, it clearly lists all the files that are in directory 1, but many of them are already in directory 2. I can see this by just looking through Windows Explorer and looking at file names. What am I missing?

EDIT:

I believe the problem is in the file compare section. I am trying to get it to ignore the case of the file extension. I have tried this:

    class FileCompare : System.Collections.Generic.IEqualityComparer<System.IO.FileInfo>
{
    public FileCompare() { }

    public bool Equals(System.IO.FileInfo f1, System.IO.FileInfo f2)
    {
        //return (f1.Name.ToUpper == f2.Name.ToUpper &&
        //        f1.Length == f2.Length);

        return (string.Equals(f1.Name, f2.Name, StringComparison.OrdinalIgnoreCase) && f1.Length == f2.Length);
    }

    public int GetHashCode(System.IO.FileInfo fi)
    {
        string s = String.Format("{0}{1}", fi.Name, fi.Length);
        return s.GetHashCode();
    }
}

But that is still not working. You can see I commented out another attempt to just make everything upper case in the comparison, but it wouldn't take that.

like image 787
Robert Wiglesworth Avatar asked Dec 27 '22 04:12

Robert Wiglesworth


2 Answers

You are going to need to use the overloaded version of Except() and pass it a custom implementation of IEqualityComparer which indicates exactly your criteria for what defines an exact match of two FileInfo objects.

See the example here and modify to your own needs: http://msdn.microsoft.com/en-us/library/bb336390.aspx

like image 109
EkoostikMartin Avatar answered Dec 28 '22 23:12

EkoostikMartin


There's an example on MSDN that shows you how to do this.

Create your IEqualityComparer implementation

class FileCompare : System.Collections.Generic.IEqualityComparer<System.IO.FileInfo>
{
    public FileCompare() { }

    public bool Equals(System.IO.FileInfo f1, System.IO.FileInfo f2)
    {
        return (f1.Name == f2.Name &&
                f1.Length == f2.Length);
    }

    public int GetHashCode(System.IO.FileInfo fi)
    {
        string s = String.Format("{0}{1}", fi.Name, fi.Length);
        return s.GetHashCode();
    }
}

Then use the Except overload with your comparer.

var queryList1Only = (from file in list1
                      select file).Except(list2, myFileCompare);
like image 30
keyboardP Avatar answered Dec 29 '22 00:12

keyboardP