查找2个巨区(文本)文件之间的更改

时间:2011-03-22 13:20:34

标签: c# .net text large-files

我可以访问.com区域文件。区域文件是一个文本文件,其中包含域名列表及其名称服务器。它遵循以下格式:

mydomain NS ns.mynameserver.com.
mydomain NS ns2.mynameserver.com.
anotherdomain NS nameservers.com.
notinalphadomain NS ns.example.com.
notinalphadomain NS ns1.example.com.
notinalphadomain NS ns2.example.com.

正如您所看到的,每个域可以有多行(当有多个名称服务器时),并且文件 NOT 按字母顺序。 这些文件的大小约为 7GB

我正在尝试获取上一个文件和新文件,并将它们进行比较以查找:

  1. 已添加哪些域
  2. 已移除哪些域
  3. 更改了域名服务器的域名
  4. 由于7GB太大而无法将整个文件加载到内存中,显然我需要在流中读取。我目前认为最好的方法是对两个文件进行多次传递。字母表中每个字母的一次传递,加载第一次传递中以'a'开头的所有域。 一旦我从旧文件和新文件中获得所有“a”域,我就可以在内存中进行非常简单的比较以找到更改。

    问题是,即使按字母读取char,并按照我能够想到的优化,每次传递文件大约需要 200-300秒 ,收集当前通行证的所有域名。因此,我认为在当前状态下,我正在查看大约一个小时来处理文件,甚至没有将更改存储在数据库中(这将花费更多时间)。这是在一个双四核xeon服务器上,所以给它增加更多的马力对我来说不是一个选择。 这个时间可能不是一个破坏者,但我希望有人对如何加快速度有一些明智的想法......不可否认,我还没有尝试过async IO,这是我的下一步。

    提前感谢任何想法!

4 个答案:

答案 0 :(得分:5)

准备数据可能会有所帮助,包括最佳代码类型:不成文的类型以及执行速度。

cat yesterday-com-zone | tr A-Z a-z | sort > prepared-yesterday
cat today-com-zone | tr A-Z a-z | sort > prepared-today

现在,您的程序执行一个非常简单的差异算法,您甚至可以使用diff:

diff prepared-today prepared-yesterday

编辑:

另一种解决方案,可以在diff执行时间的可能成本下删除一些额外的处理。这也假定使用GnuWin32 CoreUtils:

sort -f <today-com-zone >prepared-today
sort -f <yesterday-com-zone >prepared-yesterday
diff -i prepared-today prepared-yesterday

该输出将是添加,删除和更改的列表。每个区域不一定有1个更改记录(考虑当按顺序按字母顺序删除两个域时会发生什么)。您可能需要使用diff的选项来强制它不检查上下文的多行,以避免大量的误报变化。

您可能需要编写程序来获取两个已排序的输入文件,然后按锁定步骤,​​每个区域运行它们。在TODAY文件中找到新区域时,这是一个新区域。当在YESTERDAY文件中找到“新”区域(但今天丢失)时,这是一个删除。当在两个文件中找到“相同”区域时,则比较NS记录。这不是改变,也不是名称服务器的改变。

答案 1 :(得分:4)

答案 2 :(得分:3)

这与Google采访问题非常类似,例如“假设您有一百万个32位整数的列表,您希望按升序打印,而您正在处理的计算机只有2 MB RAM,你会怎么解决这个问题?“

答案(或者更确切地说,一个有效的答案)是将列表分解为可管理的块,对每个块进行排序,然后应用合并操作来生成最终的排序列表。

所以我想知道类似的方法是否适用于此。就像从第一个列表开始一样,读取尽可能多的数据,因为您可以立即在内存中高效地工作。对它进行排序,然后将已排序的块写入磁盘。重复此操作,直到您处理完整个文件,然后合并这些块来构造单个已排序的数据集(此步骤是可选的...您可以使用文件1中的所有已排序块以及来自文件1的所有已排序块进行最终比较文件2)。

对第二个文件重复上述步骤,然后打开两个已排序的数据集,并一次读取一行。如果线匹配,则前进到下一行。否则记录结果集(或输出文件)中的差异,然后将具有字典“较小”值的文件推进到下一行,然后重复。

不确定它会有多快,但它几乎肯定比通过每个文件26次更快(你有1次传递来构建块,1次传递来合并块,1次传递来比较已排序的数据集)。

那,或使用数据库。

答案 3 :(得分:2)

您应该阅读每个文件一次并将其保存到数据库中。然后,您可以使用数据库查询执行所需的任何分析。数据库旨在快速处理和处理大量数据。

第一次将所有数据读入数据库仍然相当慢,但您不必多次读取文件。