2010-12-08 121 views
1
 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

所有目录名是相同的,为什么你需要让他们在LINQ查询结果?只需从dir1中取出。 – 2010-12-08 13:00:36

回答

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)); 
+0

@Fredrik黑暗:我不能给这样的..我比较基于名称和长度的文件只..但我必须写名称和目录名称....如果我把x和点意味着它只显示名称和长度只有 – bala3569 2010-12-08 11:59:26