如何比较两个大型CSV文件并获取差异文件

我需要逐行比较2个csv(大文件)并在单独的文件中写入差异行。 一个文件中的行可以出现在第二个文件中的任何位置。 我需要比较整行。 有什么指针吗?

一种常见的方法是为一个文件中的每个行计算哈希码(最好是较小的一个)。 然后将整个文件放入哈希表中。 这将是较小文件的索引。

之后,浏览更大的文件。 对于每一行计算其哈希值。 然后查看索引。 如果那里没有这样的哈希码,那么这一行就是差异。 否则,如果存在这样的哈希代码(可能多于一行将具有相同的哈希),则执行源行与哈希表中所有冲突行的完整比较,并查看是否存在重复。

现在,如果没有重复,那么源文件中的行也是唯一的,并将其推送到输出。

否则,如果存在重复,您可能希望从哈希表中删除该副本并跳过输入行。 这意味着两个文件中的两行已被检测为相等,并将相互抵消。

完成更大的文件后,您需要决定如何处理哈希表中的其余行。 您可能希望将所有这些推送到输出,因为那些是另一个文件中不存在的行。

现在我将尝试概述伪代码:

 dict = new dictionary> -- Indexing phase foreach row in file1 code = hash(row) if dict.contains(code) then dict[hash].add(row) else dict[hash] = new list(row) -- Comparison phase foreach row in file2 code = hash(row) bool unique = true if dict.contains(code) then foreach indexedRow in dict[code] if indexedRow is the same as row then begin unique = false remove indexedRow from dict[code] end if unique then push row to output -- Finalization phase foreach row in dict push row to output 

该解决方案的最高质量是其运行时复杂度为O(M + N),其中M和N是每个文件中的行数。 它的缺点是索引需要O(min(M,N))内存。

快而脏:

 private void DoSomething() { var lines1 = File.ReadAllLines(@"file1.csv"); var lines2 = File.ReadAllLines(@"file2.csv"); var diff1From2 = FindDifferences(lines1, lines2); var diff2From1 = FindDifferences(lines2, lines1); var diffs = new List(diff1From2); diffs.AddRange(diff2From1); File.WriteAllLines(@"file3.csv", diffs); } private static string[] FindDifferences(string[] linesFirst, string[] linesSecond) { return (from line1 in linesFirst let isLineEqual = linesSecond.Any(line2 => line1 == line2) where isLineEqual == false select line1).ToArray(); }