java8实现:利用java-diff-utils库,将两个文件夹下的同名大数据量文件进行对比,将是否存在、差异文件的差异数据输出到result文件中。要求该方法可以读取jar包中的文件夹,减少嵌套循环,提高性能
时间: 2024-02-17 10:01:17 浏览: 72
usefull-views---utils:一些有用的观点
首先,需要在Maven中导入java-diff-utils库的依赖:
```
<dependency>
<groupId>com.googlecode.java-diff-utils</groupId>
<artifactId>diffutils</artifactId>
<version>1.3.0</version>
</dependency>
```
然后,我们可以编写如下的代码实现文件夹对比:
```java
import difflib.Delta;
import difflib.DiffUtils;
import difflib.Patch;
import java.io.*;
import java.util.*;
public class FolderComparator {
public static void main(String[] args) throws IOException {
String folder1 = "folder1";
String folder2 = "folder2";
String resultFile = "result.txt";
compareFolders(folder1, folder2, resultFile);
}
public static void compareFolders(String folder1, String folder2, String resultFile) throws IOException {
Map<String, File> files1 = getFilesMap(folder1);
Map<String, File> files2 = getFilesMap(folder2);
Set<String> allFileNames = new HashSet<>(files1.keySet());
allFileNames.addAll(files2.keySet());
try (PrintWriter writer = new PrintWriter(new File(resultFile))) {
for (String fileName : allFileNames) {
File file1 = files1.get(fileName);
File file2 = files2.get(fileName);
if (file1 == null) {
writer.println(String.format("%s\t%s\t%s", fileName, "not exist", getFilePathRelativeToFolder(folder2, file2)));
} else if (file2 == null) {
writer.println(String.format("%s\t%s\t%s", fileName, "not exist", getFilePathRelativeToFolder(folder1, file1)));
} else {
if (isLargeFile(file1) || isLargeFile(file2)) {
compareLargeFiles(file1, file2, writer);
} else {
compareSmallFiles(file1, file2, writer);
}
}
}
}
}
private static Map<String, File> getFilesMap(String folder) {
Map<String, File> filesMap = new HashMap<>();
File folderFile = new File(folder);
if (!folderFile.exists() || !folderFile.isDirectory()) {
return filesMap;
}
File[] files = folderFile.listFiles();
if (files == null) {
return filesMap;
}
for (File file : files) {
if (file.isDirectory()) {
filesMap.putAll(getFilesMap(file.getPath()));
} else {
filesMap.put(file.getName(), file);
}
}
return filesMap;
}
private static void compareSmallFiles(File file1, File file2, PrintWriter writer) throws IOException {
List<String> lines1 = readAllLines(file1);
List<String> lines2 = readAllLines(file2);
Patch patch = DiffUtils.diff(lines1, lines2);
if (!patch.getDeltas().isEmpty()) {
writer.println(String.format("%s\t%s", file1.getName(), file2.getName()));
for (Delta delta : patch.getDeltas()) {
writer.println(delta);
}
}
}
private static void compareLargeFiles(File file1, File file2, PrintWriter writer) throws IOException {
try (InputStream inputStream1 = new FileInputStream(file1); InputStream inputStream2 = new FileInputStream(file2)) {
BufferedReader reader1 = new BufferedReader(new InputStreamReader(inputStream1));
BufferedReader reader2 = new BufferedReader(new InputStreamReader(inputStream2));
List<String> lines1 = new ArrayList<>();
List<String> lines2 = new ArrayList<>();
String line;
while ((line = reader1.readLine()) != null) {
lines1.add(line);
}
while ((line = reader2.readLine()) != null) {
lines2.add(line);
}
Patch patch = DiffUtils.diff(lines1, lines2);
if (!patch.getDeltas().isEmpty()) {
writer.println(String.format("%s\t%s", file1.getName(), file2.getName()));
for (Delta delta : patch.getDeltas()) {
writer.println(delta);
}
}
}
}
private static List<String> readAllLines(File file) throws IOException {
try (InputStream inputStream = new FileInputStream(file)) {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
List<String> lines = new ArrayList<>();
String line;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
return lines;
}
}
private static boolean isLargeFile(File file) {
return file.length() > 1024 * 1024;
}
private static String getFilePathRelativeToFolder(String folder, File file) {
return file.getPath().substring(folder.length() + 1);
}
}
```
该代码会将文件夹中的所有文件名存入一个Set中,并遍历Set中的每个文件名,对比两个文件夹下同名的文件。如果两个文件夹下都不存在同名文件,将输出该文件名和两个文件夹的路径。如果存在同名文件,将根据文件大小决定是使用一次性读取还是逐行读取的方式进行文件内容的比较,并将比较结果输出到result文件中。
阅读全文