比较两个文本文件的最快方法是什么,不将移动的行计算为不同

我有两个文件非常大,每个文件50000行。 我需要比较这两个文件并确定更改。 但是,如果一条线存在于不同位置,则不应该显示为不同。

例如,考虑一下
文件A.txt

xxxxx yyyyy zzzzz 

文件B.txt

 zzzzz xxxx yyyyy 

所以如果这是文件的内容。 我的代码应该输出为xxxx(或xxxx和xxxxx)。

当然,最简单的方法是将文件的每一行存储在一个

 List 

并与其他人比较

 List. 

但这似乎需要花费很多时间。 我也尝试在java中使用DiffUtils。 但它不会将不同行号中的行识别为相同。 那么还有其他算法可以帮助我吗?

可能使用Set是最简单的方法:

 Set set1 = new HashSet(FileUtils.readLines(file1)); Set set2 = new HashSet(FileUtils.readLines(file2)); Set similars = new HashSet(set1); similars.retainAll(set2); set1.removeAll(similars); //now set1 contains distinct lines in file1 set2.removeAll(similars); //now set2 contains distinct lines in file2 System.out.println(set1); //prints distinct lines in file1; System.out.println(set2); //prints distinct lines in file2 

通常,HashSet是最好的解决方案,但是当我们处理字符串时,有两种可能的解决方案:

  1. 将一个文件保存为HashSet并尝试在其中查找其他文件的行。

  2. 将一个文件保存为Trie并尝试在其中查找其他文件的行

在这篇文章中,您可以找到HashSets和Tries之间的比较如何在Hash Table和Trie(前缀树)之间进行选择?

您需要跟踪相同记录可能在文件中出现多次的情况。 例如,如果记录在文件A中出现两次而在文件B中出现一次,则需要将其记录为额外记录。

由于我们必须跟踪发生的次数,您需要以下之一:

  1. 一个Multiset
  2. 从记录到整数的映射,例如Map

使用Multiset,您可以添加和删除记录,它将跟踪记录添加的次数(Set不会这样做 – 它拒绝添加已经存在的记录)。 使用Map方法,您必须做一些工作,以便整数跟踪出现的次数。 让我们考虑一下这种方法(MultiSet更简单)。

使用地图,当我们谈论“添加”记录时,您会查看地图中是否有该字符串的条目。 如果有,请将值替换为该键的值+ 1。 如果没有,请创建值为1的条目。当我们谈论“删除条目”时,查找该键的条目。 如果找到它,请将值替换为值-1。 如果将值减小为0,请删除该条目。

  1. 为每个文件创建一个Map。
  2. 读取其中一个文件的记录
  3. 检查另一个Map中是否存在该记录。
  4. 如果它存在于另一个Map中,则删除该条目(参见上面的含义)
  5. 如果它不存在,请将其添加到此文件的Map(参见上文)
  6. 重复直到结束,交替文件。

两张地图的内容将为您提供该文件中出现的记录,而不是另一张。

我们继续这样做,而不是预先构建地图,可以降低内存使用率,但可能不会对性能产生很大影响。

您可以先尝试解析第一个文件,将所有行存储在HashMap中 ,然后检查是否存在第二个文件的每一行的映射。

不过,这仍然是O(n)。

只需使用与BufferedReader的字节比较。 这将是比较两个文件的最快方法。 从一个文件中读取一个字节块,并将其与另一个文件的字节块进行比较。 首先检查文件长度是否相同。

或者只使用FileUtils.contentEquals(file1, file2); 来自org.apache.commons.io.FileUtils

您可以使用FileUtils.contentEquals(file1,file2)

它将比较2个文件的内容。

在此处查找更多信息