Java 比较两个文本文件的最快方法是什么,不将移动的行视为不同
我有两个非常大的文件,比如说每个50000行。我需要比较这两个文件并确定更改。但是,如果一条线位于不同的位置,则不应将其显示为不同的 对于EG,考虑这一点 文件A.txtJava 比较两个文本文件的最快方法是什么,不将移动的行视为不同,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>.
xxxxx
yyyyy
zzzzz
文件B.txt
zzzzz
xxxx
yyyyy
如果这是文件的内容。我的代码的输出应该是xxxx(或xxxx和xxxxx)
当然,最简单的方法是将文件的每一行存储在
List< String>
List
和其他的比较
List< String>.
列表。
但这似乎需要很多时间。我还尝试在java中使用DiffUtils。但它不能识别不同行号中的行。那么还有其他算法可以帮助我吗?一般来说,哈希集是最好的解决方案,但当我们处理字符串时,有两种可能的解决方案:
在这篇文章中,您可以找到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);