LINQ 与 C# 中的相交方法
我正在尝试使用相交方法从两个文件夹中获取相同的文件。 所有文件夹中的 123.xml 文件都是相同的(内容、日期、大小没有变化)。
Scores\Content\123.xml
Scores\Content\hi.xml
Scores\123.xml
Power\Content\123.xml
Power\Content\helo.xml
Power\123.xml
这是来自 C# 代码
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);
queryCommonFiles 仅从 Content 文件夹返回 123.xml,而不返回另一个。
这是来自 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();
}
}
:
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);
}
这会生成 list1 的 hi.xml 和 list2 的 helo.xml。正如我所说,相交方法只有一个 123.xml。
任何建议将不胜感激
谢谢,
I am trying to obtain the same files using Intersect method from two folders.
123.xml files 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,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我只是改变了Equals方法来达到想要的结果
I just changed the Equals method to achieve the desired results
一切看起来都不错。确保
Scores\123.xml
和Power\123.xml
具有相同的长度。Everything looks OK. Make sure both
Scores\123.xml
andPower\123.xml
have the same length.因为您仅使用 FileInfo.Name 和 FileInfo.Length 进行比较,所以 Content\123.xml 与 123.xml 相同(假设两个文件具有相同的大小,我猜测您的测试数据就是这种情况)。
因此,就您的 FileCompare 类而言,您的输入集合包含重复项。根据 MSDN,Intersect 评估不同元素在每组中。
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.