var dir1Files = dir1.GetFiles("*", SearchOption.AllDirectories).Select(x => new { x.Name, x.Length });
var dir2Files = dir2.GetFiles("*", SearchOption.AllDirectories).Select(x => new { x.Name, x.Length });
var onlyIn1 = dir1Files.Except(dir2Files).Select(x => new { x.Name });
File.WriteAllLines(@"d:\log1.txt", foo1);
这里我将根据名称和文本文件中的两个文件进行比较... 但我需要写名字和目录名...但我不能选择像这样的目录名
var onlyIn1 = dir1Files.Except(dir2Files).Select(x => new { x.Name,x.DirectoryName });
有什么建议吗?
答案 0 :(得分:3)
使用FullName
解决您的问题吗?
var onlyIn1 = dir1Files.Except(dir2Files).Select(x => new { x.FullName });
或者,您可以在Select
语句中组合自定义字符串:
// get strings in the format "file.ext, c:\path\to\file"
var onlyIn1 = dir1Files.Except(dir2Files).Select(x =>
string.Format("{0}, {1}", x.Name, x.Directory.FullName));
为了能够在对象中使用此信息,请不要在第一步中创建信息有限的匿名类型,而是保留完整的FileInfo
个对象:
var dir1Files = dir1.GetFiles("*", SearchOption.AllDirectories);
var dir2Files = dir2.GetFiles("*", SearchOption.AllDirectories);
<强>更新强>
代码示例中的真正问题是Except
将使用默认相等比较器进行比较。对于大多数类型(当然在匿名类型的情况下),这意味着它将比较对象引用。由于您有两个包含FileInfo
个对象的列表,Except
将返回第一个列表中的所有对象,其中第二个列表中找不到相同的对象实例。由于第一个列表中的所有对象实例都不存在于第二个列表中,因此将返回第一个列表中的所有对象。
为了解决这个问题(并且仍然可以访问您要存储的数据),您需要使用Except
overload that accepts an IEqualityComparer<T>
。首先,让我们创建IEqualityComparer
:
class FileInfoComparer : IEqualityComparer<FileInfo>
{
public bool Equals(FileInfo x, FileInfo y)
{
// if x and y are the same instance, or both are null, they are equal
if (object.ReferenceEquals(x,y))
{
return true;
}
// if one is null, they are not equal
if (x==null || y == null)
{
return false;
}
// compare Length and Name
return x.Length == y.Length &&
x.Name.Equals(y.Name, StringComparison.OrdinalIgnoreCase);
}
public int GetHashCode(FileInfo obj)
{
return obj.Name.GetHashCode() ^ obj.Length.GetHashCode();
}
}
现在您可以使用该比较器来比较目录中的文件:
var dir1 = new DirectoryInfo(@"c:\temp\a");
var dir2 = new DirectoryInfo(@"c:\temp\b");
var dir1Files = dir1.GetFiles("*", SearchOption.AllDirectories);
var dir2Files = dir2.GetFiles("*", SearchOption.AllDirectories);
var onlyIn1 = dir1Files
.Except(dir2Files, new FileInfoComparer())
.Select(x => string.Format("{0}, {1}", x.Name, x.Directory.FullName));