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

时间:2015-09-14 12:51:43

标签: java file comparison

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

例如,请考虑这一点 文件A.txt

xxxxx
yyyyy
zzzzz    

文件B.txt

zzzzz
xxxx
yyyyy  

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

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

List< String>

并与其他

进行比较
List< String>.

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

7 个答案:

答案 0 :(得分:2)

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

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

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

  3. 在这篇文章中,你可以找到HashSets和Tries How Do I Choose Between a Hash Table and a Trie (Prefix Tree)?

    之间的比较

答案 1 :(得分:1)

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

Set<String> set1 = new HashSet<String>(FileUtils.readLines(file1));

Set<String> set2 = new HashSet<String>(FileUtils.readLines(file2));


Set<String> similars = new HashSet<String>(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

答案 2 :(得分:1)

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

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

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

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

    1. 为每个文件创建一个地图。
    2. 读取其中一个文件的记录
    3. 检查另一张地图中是否存在该记录。
    4. 如果它存在于另一个Map中,请删除该条目(请参阅上文,了解其含义)
    5. 如果它不存在,请将其添加到此文件的地图中(见上文)
    6. 重复直到结束,交替文件。
    7. 两张地图的内容将为您提供该文件中出现的记录,而不是另一张。

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

答案 3 :(得分:0)

我认为这会很有用,

   BufferedReader reader1 = new BufferedReader(new FileReader("C:\\file1.txt"));

    BufferedReader reader2 = new BufferedReader(new FileReader("C:\\file2.txt"));

    String line1 = reader1.readLine();

    String line2 = reader2.readLine();

    boolean areEqual = true;

    int lineNum = 1;

    while (line1 != null || line2 != null)
    {
        if(line1 == null || line2 == null)
        {
            areEqual = false;

            break;
        }
        else if(! line1.equalsIgnoreCase(line2))
        {
            areEqual = false;

            break;
        }

        line1 = reader1.readLine();

        line2 = reader2.readLine();

        lineNum++;
    }

    if(areEqual)
    {
        System.out.println("Two files have same content.");
    }
    else
    {
        System.out.println("Two files have different content. They differ at line "+lineNum);

        System.out.println("File1 has "+line1+" and File2 has "+line2+" at line "+lineNum);
    }

    reader1.close();

    reader2.close();

答案 4 :(得分:-1)

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

但这仍然是O(n)。

答案 5 :(得分:-1)

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

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

答案 6 :(得分:-1)

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

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

查找更多信息here