提问人:Andres Acosta 提问时间:3/2/2023 更新时间:3/2/2023 访问量:303
逐行比较两个文件(不按顺序排列)的最有效方法是什么?[已结束]
What is the most effective way to compare two files line by line (lines are not ordered)? [closed]
问:
我有两个文件,大约有 20,000 行,我需要比较它们,问题是这些行的顺序不同,每一行都是唯一的,因为它们是 DB 的记录,但文件一的行可以是第二个文件中的第 15.000 行,我试图浏览第一个文件的一行,并使用BufferReader但是对于每行大约需要10秒17.000次会很长的时间,有没有更有效的方法可以做到这一点? .
答:
2赞
impossible-sudoku
3/2/2023
#1
使用哈希函数
- 为第一个文件中的每一行生成一个哈希值。您可以使用 MD5 或 SHA-1 等哈希函数
- 将哈希值存储在哈希表或字典数据结构中,以哈希值为键,以行号为值。
- 循环访问第二个文件中的每一行,为每行生成一个哈希值,并检查是否与 file1 字典匹配
法典
import java.io.*;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.util.HashMap;
public class FileComparator {
public static void main(String[] args) throws Exception {
File file1 = new File("file1.txt");
File file2 = new File("file2.txt");
HashMap<String, String> file1Hashes = getFileHashes(file1);
HashMap<String, String> file2Hashes = getFileHashes(file2);
for (String key : file1Hashes.keySet()) {
if (!file2Hashes.containsKey(key)) {
System.out.println(key + " not found in file2");
} else if (!file1Hashes.get(key).equals(file2Hashes.get(key))) {
System.out.println(key + " differs in file1 and file2");
}
}
for (String key : file2Hashes.keySet()) {
if (!file1Hashes.containsKey(key)) {
System.out.println(key + " not found in file1");
}
}
}
private static HashMap<String, String> getFileHashes(File file) throws Exception {
HashMap<String, String> hashes = new HashMap<>();
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
while ((line = reader.readLine()) != null) {
hashes.put(line, getHash(line));
}
reader.close();
return hashes;
}
private static String getHash(String line) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hashBytes = md.digest(line.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b : hashBytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}
评论
0赞
impossible-sudoku
3/2/2023
这对你不起作用?
0赞
Andres Acosta
3/2/2023
这不会以内存问题结束吗?我的意思是在地图中存储 17,000 个项目,可以吗?
0赞
impossible-sudoku
3/2/2023
我的意思是,现在大多数计算机至少有几GB内存。
1赞
alalalala
3/2/2023
或者最好用行的哈希值作为键,遍历第一张地图,然后用第一张地图的键从第二张地图中获取
1赞
Andres Acosta
3/2/2023
@impossible-sudoku 我接受了你的请求,但我使用 String.hashCode() 值作为每行的键,它工作正常,非常感谢。
评论
bash -c 'diff <(sort text2) <(sort text1)'