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 compare two files based on the name and the entry in the text file ... But I need to write the name along with the directory name ... But I can not select a directory name like this
var onlyIn1 = dir1Files.Except(dir2Files).Select(x => new { x.Name,x.DirectoryName }); Any suggestion?
Does FullName Solve Your Problem?
var onlyIn1 = dir1Files.Except(dir2Files).Select(x => new { x.FullName }); Alternatively, you can put together a custom string in a 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)); To be able to use this information in objects, do not create anonymous types with limited information in the first steps, but save complete FileInfo objects:
var dir1Files = dir1.GetFiles("*", SearchOption.AllDirectories); var dir2Files = dir2.GetFiles("*", SearchOption.AllDirectories); Update
The real problem in your code example is that Except will compare using the default equalizer. For most types (and, of course, in the case of anonymous types), this means that it will compare references to objects. Since you have two lists with FileInfo objects, Except will return all objects from the first list, where the same object instances will not be found in the second. Since none of the instances of objects in the first list is also present in the second, all objects from the first list will be returned.
To fix this (and still have access to the data you want to save), you will need to use the Except overload , which accepts IEqualityComparer<T> . First create an 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 this comparator to compare files in 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));