comparing two folders for non identical files?

后端 未结 1 1628
北荒
北荒 2021-01-16 03:52
     var dir1Files = dir1.GetFiles(\"*\", SearchOption.AllDirectories).Select(x => new { x.Name, x.Length });
    var dir2Files = dir2.GetFiles(\"*\", SearchOptio         


        
相关标签:
1条回答
  • 2021-01-16 04:31

    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 讨论(0)
提交回复
热议问题