C#-比较2个文件夹-使EqualityComparer

时间:2018-07-31 07:16:30

标签: c# linq synchronization compare md5

我需要您的帮助。

我正在编写一个程序来在2个文件夹之间进行同步。

我想拥有3个列表:

  1. 在两个文件夹之间具有相同文件夹和文件的列表。

  2. 在文件夹A中仅包含文件和文件夹的列表。

  3. 在文件夹B中仅包含文件和文件夹的列表。

我有定义项目(文件/文件夹)的类。

我正在尝试为2个列表制作EqualityComparer,其中包含2个文件夹的所有内容。

我基于此链接建立了解决方案: compare folders

我不能制造出符合我的目的的EqualityComparer,最终以3:

  1. FileMd5EqualityComparer-使用md5完整扫描2个文件夹以获取完整身份-在拆分为列表之前用于检查完整身份。
  2. FileSameFilesCompare-应该为我提供的文件夹和文件具有相同的名称但不同-用于(1)列表。
  3. FileCompare-应该为我在文件夹之间进行任何更改,但没有相同名称但不同的文件/文件夹。(没有上面的比较)-用于(2)和(3)列表。

这是他们的代码:

FileMd5EqualityComparer:

public class FileMd5EqualityComparer : IEqualityComparer<FSInfo>
    {
        public bool Equals(FSInfo x, FSInfo y)
        {
            // Use basic comparison
            if(x == y)
            {
                return true;
            }

            // if one of both parameters is null, they can't be
            // the same - Except both are null, but this case is
            // handled above.
            if(x == null || y == null)
            {
                return false;
            }

            // If both file paths are the same, the
            // files must be the same.
            if(x.FullName == y.FullName)
            {
                return true;
            }

            if(!x.IsFile ^ !y.IsFile)
                return false;

            // The files can't be equal if they don't
            // have the same size
            // if(x != y.Length)
            // {
            //     return false;
            // }

            // If their name is not the same, they cant be the same.
            if(x.Name != y.Name)
            {
                return false;
            }

            if ((!x.IsFile && !y.IsFile))
            {
                // if they are the same relative then they are the same
                // else they are not the same
                if (x.RelativePath == y.RelativePath)
                    return true;
                else
                    return false;
            }

            // At last, compare the MD5 of the files.
            var md5X = "";
            var md5Y = "";
            try
            {
                md5X = GetMd5(x.FullName);
                md5Y = GetMd5(y.FullName);
            }
            catch(IOException ioex)
            {
                Console.WriteLine(ioex.Message);
            }

            return md5X == md5Y;
        }

        public int GetHashCode(FSInfo obj)
        {
            return obj.GetHashCode();
        }


        private string GetMd5(string filePath)
        {
            using (var md5 = MD5.Create())
            {
                using (var stream = File.OpenRead(filePath))
                {
                    return Encoding.Default.GetString(md5.ComputeHash(stream));
                }
            }
        }
    }

FileSameFilesCompare:

public class FileSameFilesCompare : IEqualityComparer<FSInfo>
{
    public bool Equals(FSInfo x, FSInfo y)
    {

        // Use basic comparison
        if(x == y)
        {
            return true;
        }

        // if one of both parameters is null, they can't be
        // the same - Except both are null, but this case is
        // handled above.
        if(x == null || y == null)
        {
            return false;
        }

        if(x.FullName == y.FullName)
        {
            return true;
        }

        if(!x.IsFile ^ !y.IsFile)
            return false;

        if ((!x.IsFile && !y.IsFile))
        {
            // if they are the same relative then they are the same^M
            // else they are not the same^M
            if (x.RelativePath == y.RelativePath)
                return true;
            else
                return false;
        }

        var md5X = "";
        var md5Y = "";
        try
        {
            md5X = GetMd5(x.FullName);
            md5Y = GetMd5(y.FullName);
        }
        catch(IOException ioex)
        {
            Console.WriteLine(ioex.Message);
        }
       // if(x.Name == y.Name && 
       //    (x.DateModified != y.DateModified || x.DateCreated != y.DateCreated || md5X != md5Y)) 
        if(x.Name == y.Name && (md5X != md5Y)) // old approch
        {
            return true;
        }
        return false;
    }

    public int GetHashCode(FSInfo obj)
    {
        string s = String.Format("{0}", obj.Name); 
        return s.GetHashCode();
    }

    private string GetMd5(string filePath)
    {
        using (var md5 = MD5.Create())
        {
            using (var stream = File.OpenRead(filePath))
            {
                return Encoding.Default.GetString(md5.ComputeHash(stream));
            }
        }
    }
}

FileCompare:

public class FileCompare : IEqualityComparer<FSInfo>
{
        public bool Equals(FSInfo x, FSInfo y)
        {

            // Use basic comparison
            if(x == y)
            {
                return true;
            }

            // if one of both parameters is null, they can't be
            // the same - Except both are null, but this case is
            // handled above.
            if(x == null || y == null)
            {
                return false;
            }

            if(x.FullName == y.FullName)
            {
                return true;
            }

            if(!x.IsFile && !y.IsFile)
                return true;

            if(!x.IsFile || !y.IsFile)
                return false;

            if(x.Name == y.Name) 
            {
                return true;
            }
            return false;
        }

        public int GetHashCode(FSInfo obj)
        {
            string s = String.Format("{0}{1}", obj.Name,obj.RelativePath);  
            return s.GetHashCode();
        }
}

我这样使用它们:

    bool areIdentical = list1.FSOs.SequenceEqual(list2.FSOs, myFileMd5Compare);  

    if (areIdentical == true)  
    {  
        Messages.NullReason = Messages.SameFoldersContent;
        return null;  
    } 

    List<FSInfo> modiList = new List<FSInfo>();
    var toChangeList = list1.FSOs.Intersect(list2.FSOs, same);
    var toDeleteList = (from file in list2.FSOs
                        select file).Except(list1.FSOs, myFileCompare);
    var toInsertList = (from file in list1.FSOs
                        select file).Except(list2.FSOs, myFileCompare);

嗯,它不能很好地工作,我的工具似乎太复杂了。

在此方面,我需要您的帮助。 谢谢!

0 个答案:

没有答案