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

Java 比较两个文本文件的最快方法是什么,不将移动的行视为不同,java,file,comparison,Java,File,Comparison,我有两个非常大的文件,比如说每个50000行。我需要比较这两个文件并确定更改。但是,如果一条线位于不同的位置,则不应将其显示为不同的 对于EG,考虑这一点 文件A.txt xxxxx yyyyy zzzzz 文件B.txt zzzzz xxxx yyyyy 如果这是文件的内容。我的代码的输出应该是xxxx(或xxxx和xxxxx) 当然,最简单的方法是将文件的每一行存储在 List< String> List 和其他的比较 List< String>.

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

对于EG,考虑这一点 文件A.txt

xxxxx
yyyyy
zzzzz    
文件B.txt

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

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

List< String>
List
和其他的比较

List< String>.
列表

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

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

  • 将一个文件保存为哈希集,并尝试在其中查找其他文件的行

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


  • 在这篇文章中,您可以找到hashset和trys之间的比较。您可以尝试先解析第一个文件,将所有行存储在中,然后检查第二个文件的每一行是否存在映射


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

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


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

    可能使用
    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
    
    Set set1=newhashset(FileUtils.readLines(file1));
    Set set2=新的HashSet(FileUtils.readLines(file2));
    Set similars=新哈希集(set1);
    相似的保留体(set2);
    set1.移除所有(类似)//现在,set1在file1中包含不同的行
    set2.移除所有(类似)//现在,set2在file2中包含不同的行
    系统输出打印项次(set1)//在文件1中打印不同的行;
    系统输出打印项次(set2)//在文件2中打印不同的行
    
    您可以使用FileUtils.contentEquals(file1,file2)

    它将比较这两个文件的内容


    查找更多信息

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

    由于我们必须跟踪事件的数量,因此您需要:

  • A
  • 从记录到整数的映射,例如映射
  • 使用Multiset,您可以添加和删除记录,它将跟踪记录的添加次数(集合不会这样做-它拒绝添加已经存在的记录)。使用映射方法,您需要做一些工作,以便整数跟踪出现的次数。让我们考虑这种方法(多集更简单)。< /P> 对于映射,当我们谈论“添加”记录时,您要查看映射中是否有该字符串的条目。如果存在,则将该键的值替换为值+1。如果没有,请创建一个值为1的条目。当我们谈论“删除条目”时,请查找该键的条目。如果找到它,请将该值替换为值-1。如果该值减小为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();
    


    您是否在Linux中部署代码??也许您可以使用简单数组(字符串[])。这会快得多。或者,如果要使用完成的实现,可以使用FileUtils.contentEquals(file1,file2);从org.apache.commons.io.FileUtils。如果您正在寻找最快的方法,那么从java调用linux的diff api,您就可以在文件中多次出现同一行了吗?如果是这样,并且同一行在一个文件中出现一次,在另一个文件中出现两次,那么这些文件是相同的吗?@prashantthakre Ya将在linux中部署。表的键和值是什么?为什么要使用一个哈希表而不是一个哈希表?哦,是的,JB NIZET,你是正确的哈什特应该是足够的。也不考虑在另一个文件中有附加的谎言的可能性,或者考虑重复行。@ DJClayworth为什么需要考虑重复行?参见问题的评论。不检查第一个文件中是否有第二行中的行。不检查同一行在两个文件中出现的次数是否相同。可以创建一个实现来检查使用HashMap(或者,正如其他人指出的,使用HashSet,这可能已经足够了)的人。这需要更多的努力,但可能还是比创建两个列表并比较每个条目要好。不允许以不同的顺序显示相同的行。不允许在不同的位置显示相同的行。@DJClayworth我们正在比较两个文件,并试图在它们之间找到不同的行,我不明白为什么重复会成为一个问题。@downvoter,你能说明下一次投票的原因吗?这会比比较两个列表更快吗?同样在这一行set2.removeAll(similars);