var dir1Files = dir1.GetFiles(\"*\", SearchOption.AllDirectories).Select(x => new { x.Name, x.Length });
var dir2Files = dir2.GetFiles(\"*\", SearchOptio
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));