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.
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
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With