I am trying to obtain the same files using Intersect method from two folders. 123.xml fi开发者_如何学Pythonles are the same (no change with content, date, size) in all the folders.
Scores\Content\123.xml
Scores\Content\hi.xml
Scores\123.xml
Power\Content\123.xml
Power\Content\helo.xml
Power\123.xml
This is from the C# code
System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(path1);
System.IO.DirectoryInfo dir2 = new System.IO.DirectoryInfo(path2);
IEnumerable<System.IO.FileInfo> list1 = dir1.GetFiles("*.*", System.IO.SearchOption.AllDirectories);
IEnumerable<System.IO.FileInfo> list2 = dir2.GetFiles("*.*", System.IO.SearchOption.AllDirectories);
FileCompare myFileCompare = new FileCompare();
bool areIdentical = list1.SequenceEqual(list2, myFileCompare);
if (areIdentical == true)
{
Console.WriteLine("the two folders are the same");
}
else
{
Console.WriteLine("The two folders are not the same");
}
var queryCommonFiles = list1.Intersect(list2, myFileCompare);
The queryCommonFiles is only returning the 123.xml from Content folder, but not the other one.
This is the code from the FileCompare
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);
}
// Return a hash that reflects the comparison criteria. According to the
// rules for IEqualityComparer<T>, if Equals is true, then the hash codes must
// also be equal. Because equality as defined here is a simple value equality, not
// reference identity, it is possible that two or more objects will produce the same
// hash code.
public int GetHashCode(System.IO.FileInfo fi)
{
string s = String.Format("{0}{1}", fi.Name, fi.Length);
return s.GetHashCode();
}
}
EDIT:
var queryList1Only = (from file in list1
select file).Except(list2, myFileCompare);
Console.WriteLine("The following files are in list1 but not list2:\n");
foreach (var v in queryList1Only)
{
Console.WriteLine(v.FullName);
}
var queryList2Only = (from file in list2
select file).Except(list1, myFileCompare);
Console.WriteLine("The following files are in list2 but not list1:\n");
foreach (var v in queryList2Only)
{
Console.WriteLine(v.FullName);
}
This produces as hi.xml for list1 and helo.xml for list2. And as I said only one 123.xml for the intersect method.
Any suggestions would be appreciated
Thanks,
I just changed the Equals method to achieve the desired results
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.Directory.Name == f2.Directory.Name &&
f1.Length == f2.Length);
}
// Return a hash that reflects the comparison criteria. According to the
// rules for IEqualityComparer<T>, if Equals is true, then the hash codes must
// also be equal. Because equality as defined here is a simple value equality, not
// reference identity, it is possible that two or more objects will produce the same
// hash code.
public int GetHashCode(System.IO.FileInfo fi)
{
string s = String.Format("{0}{1}", fi.Name, fi.Length);
return s.GetHashCode();
}
}
Everything looks OK. Make sure both Scores\123.xml
and Power\123.xml
have the same length.
Because you only compare using FileInfo.Name and FileInfo.Length, Content\123.xml is the same as 123.xml (assuming both files have the same size, which I'm guessing is the case for your test data).
Therefore, as far as your FileCompare class is concerned, your input collections contain duplicates. According to MSDN, Intersect evaluates distinct elements in each set.
精彩评论