开发者

comparing two folders for non identical files?

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

Here i am comparing two files based on name and writing in a text file... But i need to write name along with directory name...But i cannot select directory name like this

 var onlyIn1 = dir1Files.Except(dir2Files).Select(x =>开发者_如何学C new { x.Name,x.DirectoryName });

Any suggestion?


Does using FullName solve your problem?

var onlyIn1 = dir1Files.Except(dir2Files).Select(x => new { x.FullName }); 

Alternatively you could put together a custom string within the Select statement:

// 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)); 

In order to be able to use this information in the objects, don't create anonymous types with limited information in the first steps, but rather keep the full FileInfo objects:

var dir1Files = dir1.GetFiles("*", SearchOption.AllDirectories);
var dir2Files = dir2.GetFiles("*", SearchOption.AllDirectories);

Update
The real problem in your code sample is that Except will compare using the default equality comparer. For most types (and certainly in the case of anonymous types) this means that it will compare the object references. Since you have two lists with FileInfo objects, Except will return all objects from the first list, where the same object instances are not found in the second. Since none of the object instances in the first list are present also in the second, all objects from the first list will be returned.

In order to fix this (and still have access to the data that you want to store) you will need to use the Except overload that accepts an IEqualityComparer<T>. First, let's create the 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();
    }
}

Now you can use that comparer to compare the files in the directories:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜