将两个非相同文件的文件夹与对称文件进行比较[英] comparing two folders for non identical files with SymmetricDifference

本文是小编为大家收集整理的关于将两个非相同文件的文件夹与对称文件进行比较的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

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

 var difference = dir1Files.ToHashSet(); 
 difference.SymmetricExceptWith(dir2Files);

 string[] foo1 = difference.Select(c => c.Name).ToArray();
 File.WriteAllLines(@"d:\log1.txt", foo1);

在这里,我正在根据名称进行比较两个文件,并在文本文件中写入...但是我需要与此名称一起写名称比较两个非相同文件的文件夹? ...

任何建议?

编辑: 我有两个文件夹a和b ..在两个文件夹中有很多文件夹和文件. 我正在比较与对称差异的非相同文件的这两个文件夹,并将名称和目录名称写入文本文件...我的问题是对称差异正常工作,并且将两个非相同的文件名称写入日志文件...但是我必须用该目录名称编写文件名...

此代码正常工作

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 difference = dir1Files.ToHashSet();      
difference.SymmetricExceptWith(dir2Files);
string[] foo1 = difference.Select(c => c.Name).ToArray();
File.WriteAllLines(@"d:\log1.txt", foo1); 

在这里我不能像这样

string[] foo1 = difference.Select(c => c.Name+""+c.DirectoryName).ToArray();

推荐答案

我认为最好的方法是写自己的 IEqualityComparer<FileInfo> 实现了您对两个文件之间平等的定义.

public class FileInfoNameLengthEqualityComparer : EqualityComparer<FileInfo>
{
    public override bool Equals(FileInfo x, FileInfo y)
    {
        if (x == y)
            return true;

        if (x == null || y == null)
            return false;

        // 2 files are equal if their names and lengths are identical.
        return x.Name == y.Name && x.Length == y.Length;
    }

    public override int GetHashCode(FileInfo obj)
    {
        return obj == null
               ? 0  : obj.Name.GetHashCode() ^ obj.Length.GetHashCode();
    }
}

然后其余的看起来像(未经测试):

// Construct custom equality-comparer.
var comparer = new FileInfoNameLengthEqualityComparer();

// Create sets of files from each directory.
var sets = new[] { dir1, dir2 }
                 .Select(d => d.GetFiles("*", SearchOption.AllDirectories))
                 .Select(files => new HashSet<FileInfo>(files, comparer))
                 .ToArray();

// Make the first set contain the set-difference as determined 
// by the equality-comparer.
sets[0].SymmetricExceptWith(sets[1]);

// Project each file to its full name and write the file-names
// to the log-file.
var lines = sets[0].Select(fileInfo => fileInfo.FullName).ToArray();
File.WriteAllLines(@"d:\log1.txt", lines); 

本文地址:https://www.itbaoku.cn/post/1556767.html

问题描述

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

 var difference = dir1Files.ToHashSet(); 
 difference.SymmetricExceptWith(dir2Files);

 string[] foo1 = difference.Select(c => c.Name).ToArray();
 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 like this comparing two folders for non identical files?...

Any Suggestion?

EDIT: I have two folders A and B..inside that two folders lots of folders and files are there... I am comparing these two folders for non identical files with symmetric difference and write the name and directory name into a text file...my problem is symmetric difference is working fine and is writing both non identical file names into a log file...But i have to write file name with that directory name...

this code is working fine

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 difference = dir1Files.ToHashSet();      
difference.SymmetricExceptWith(dir2Files);
string[] foo1 = difference.Select(c => c.Name).ToArray();
File.WriteAllLines(@"d:\log1.txt", foo1); 

Here i cant give like this

string[] foo1 = difference.Select(c => c.Name+""+c.DirectoryName).ToArray();

推荐答案

I think the best way to do this would be to write your own IEqualityComparer<FileInfo> implementation that enforced your definition of equality between two files.

public class FileInfoNameLengthEqualityComparer : EqualityComparer<FileInfo>
{
    public override bool Equals(FileInfo x, FileInfo y)
    {
        if (x == y)
            return true;

        if (x == null || y == null)
            return false;

        // 2 files are equal if their names and lengths are identical.
        return x.Name == y.Name && x.Length == y.Length;
    }

    public override int GetHashCode(FileInfo obj)
    {
        return obj == null
               ? 0  : obj.Name.GetHashCode() ^ obj.Length.GetHashCode();
    }
}

And then the rest of it would look something like (untested):

// Construct custom equality-comparer.
var comparer = new FileInfoNameLengthEqualityComparer();

// Create sets of files from each directory.
var sets = new[] { dir1, dir2 }
                 .Select(d => d.GetFiles("*", SearchOption.AllDirectories))
                 .Select(files => new HashSet<FileInfo>(files, comparer))
                 .ToArray();

// Make the first set contain the set-difference as determined 
// by the equality-comparer.
sets[0].SymmetricExceptWith(sets[1]);

// Project each file to its full name and write the file-names
// to the log-file.
var lines = sets[0].Select(fileInfo => fileInfo.FullName).ToArray();
File.WriteAllLines(@"d:\log1.txt", lines);