我需要您的帮助。
我正在编写一个程序来在2个文件夹之间进行同步。
我想拥有3个列表:
在两个文件夹之间具有相同文件夹和文件的列表。
在文件夹A中仅包含文件和文件夹的列表。
在文件夹B中仅包含文件和文件夹的列表。
我有定义项目(文件/文件夹)的类。
我正在尝试为2个列表制作EqualityComparer,其中包含2个文件夹的所有内容。
我基于此链接建立了解决方案: compare folders
我不能制造出符合我的目的的EqualityComparer,最终以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);
嗯,它不能很好地工作,我的工具似乎太复杂了。
在此方面,我需要您的帮助。 谢谢!