C# 返回两个文件比较后添加或删除的记录
我正在比较两个文件,其中一个文件可能添加或删除了项。我正在检查这两个文件之间是否存在差异,如果存在差异,那么无论是否添加或删除了记录,这些差异是什么。我想返回那些记录(添加或删除) 根据我所拥有的信息,它告诉我文件是否删除或添加了项目,但它不会返回已添加或删除的项目。对我所缺少的任何帮助都将不胜感激C# 返回两个文件比较后添加或删除的记录,c#,winforms,C#,Winforms,我正在比较两个文件,其中一个文件可能添加或删除了项。我正在检查这两个文件之间是否存在差异,如果存在差异,那么无论是否添加或删除了记录,这些差异是什么。我想返回那些记录(添加或删除) 根据我所拥有的信息,它告诉我文件是否删除或添加了项目,但它不会返回已添加或删除的项目。对我所缺少的任何帮助都将不胜感激 foreach (ExcelRow rowA in fileA.excelRows) { if (!fileB.ContainsHash(rowA.rowHash))
foreach (ExcelRow rowA in fileA.excelRows)
{
if (!fileB.ContainsHash(rowA.rowHash))
{
MessageBox.Show("Files are NOT the same. Data was REMOVED.\n" + rowA.ToString());
}
}
foreach (ExcelRow rowB in fileB.excelRows)
{
if (!fileA.ContainsHash(rowB.rowHash))
{
MessageBox.Show("Row added" + rowB.ToString());
}
}
public List<ExcelRow> excelRows = new List<ExcelRow>();
public bool ContainsHash(byte[] hashToLook)
{
bool found;
found = false;
foreach (ExcelRow eRow in excelRows)
{
found = EqualHash(eRow.rowHash, hashToLook);
if (found)
{
break;
}
}
return found;
}
public static bool EqualHash(byte[] hashA, byte[] hashB)
{
bool bEqual ;
int i ;
bEqual = false;
if (hashA.Length == hashB.Length)
{
i = 0;
while ((i < hashA.Length) && (hashA[i] == hashB[i]))
{
i++ ;
}
if (i == hashA.Length)
{
bEqual = true;
}
}
return bEqual ;
}
计算哈希:
public ExcelInfo ReadExcel(OpenFileDialog openFileDialog)
{
var _excelFile = new ExcelQueryFactory(openFileDialog.FileName);
var _info = from c in _excelFile.WorksheetNoHeader() select c;
ExcelRow excelRow;
ExcelInfo resp;
resp = new ExcelInfo();
foreach (var item in _info)
{
excelRow = new ExcelRow();
excelRow.lstCells.Add(item.ElementAt(0));
excelRow.lstCells.Add(item.ElementAt(1));
excelRow.lstCells.Add(item.ElementAt(2));
excelRow.lstCells.Add(item.ElementAt(3));
excelRow.lstCells.Add(item.ElementAt(4));
excelRow.lstCells.Add(item.ElementAt(5));
excelRow.lstCells.Add(item.ElementAt(6));
excelRow.lstCells.Add(item.ElementAt(7));
excelRow.lstCells.Add(item.ElementAt(8));
excelRow.lstCells.Add(item.ElementAt(9));
excelRow.lstCells.Add(item.ElementAt(10));
excelRow.lstCells.Add(item.ElementAt(11));
excelRow.lstCells.Add(item.ElementAt(12));
excelRow.CalculateHash();
resp.excelRows.Add(excelRow);
}
return resp;
}
public void CalculateHash()
{
byte[] rowBytes;
byte[] cellBytes;
int pos;
int numRowBytes;
numRowBytes = 0;
foreach (string cellText in lstCells)
{
numRowBytes += NumBytes(cellText);
}
//Allocate space to calculate the HASH of a single row
rowBytes = new byte[numRowBytes];
pos = 0;
//Concatenate the cellText of each row into a single byte array
foreach (string cellText in lstCells)
{
cellBytes = GetBytes(cellText);
System.Buffer.BlockCopy(cellBytes, 0, rowBytes, pos, cellBytes.Length);
pos = cellBytes.Length;
}
rowHash = new MD5CryptoServiceProvider().ComputeHash(rowBytes);
}
调试时:
if (!fileB.ContainsHash(rowA.rowHash))
fileB包含三行,fileA包含四行
fileB=3,
rowA=文件A和(.rowHash)中的第一行是字节[16]
当我继续包含hash方法时,byte[]hashToLook=16-这不应该是rowA吗
excelRows=3(文件B)
然后
EqualHash(eRow.rowHash,hashToLook)是(文件A中的第一行,字节[16])
我把rowA传错了吗?你就快到了,只需添加两个列表来跟踪A中但不在B中的项目和B中但不在A中的项目:
var notInA = new List<ExcelRow>();
var notInB = new List<ExcelRow>();
只需更改
hashA[i]!=hashB[i]
到hashA[i]==hashB[i]
:)要得到完整的答案,需要某种类型的衍射结果
类型。。。和方法声明(这可能是OP的主要问题)。@AlexeiLevenkov如果我们从文件“A”是原始(即早期版本)的角度考虑这一点,那么“notInB”在语义上等于“Removed”,而“notInA”在语义上等于“Added”.我刚试过这个,首先它显示三个项目被删除,两个项目被添加。即使在这两个文件之间,我只删除了一个row@Masriyah您从“文件B”中删除了一行?是的-我更改了if和else语句,但现在仍然显示删除了3行,不仅仅是1行是的,我做了此更改,但我仍然得到了我上面提到的内容。请说明您是如何计算哈希的。也就是说,ExcelRow.CalculateHash
@Alex的实现我添加了上述方法。谢谢,我想我已经发现了散列计算中的错误。您需要替换pos=cellBytes.Length代码>带有pos+=cellBytes.Length代码>此外,偶尔也会发生哈希冲突。因此,如果哈希匹配,您还应该比较每个字段,以确保两行相等。虽然MD5覆盖了所有字节,但发生这种情况的可能性非常低。@Alex我想我已经非常接近了-现在它显示了我删除的行之前的行就是删除的行。例如:文件有1,2,3,4(我删除了5),它返回声明4已删除
foreach (ExcelRow rowA in fileA.excelRows)
{
if (!fileB.ContainsHash(rowA.rowHash))
{
MessageBox.Show("Files are NOT the same. Data was REMOVED.\n" + rowA.ToString());
notInB.Add(rowA);
}
}
foreach (ExcelRow rowB in fileB.excelRows)
{
if (!fileA.ContainsHash(rowB.rowHash))
{
MessageBox.Show("Row added" + rowB.ToString());
notInA.Add(rowB);
}
}