java8实现:利用java-diff-utils库,将两个文件夹下的同名大数据量文件进行对比,将是否存在、差异文件的差异数据输出到result文件中。要求该方法可以读取jar包中的文件夹,减少嵌套循环,提高性能
时间: 2024-02-16 09:05:29 浏览: 111
记录一下 Java 代码实现文件夹、文件的对比,主要包含 word、pdf、文本、图片等相关文件的对比计算,以及计算文本的相似率(重复率)、筛选出差异的文件、方便文件和文档的去重,并封装为jar包
好的,我来回答你的问题。
首先,我们需要将该文件夹下的所有同名文件进行遍历,并使用java-diff-utils库进行对比。这个过程可以使用递归来进行,同时利用Java 8的Stream API可以使代码更加简洁:
```java
public void diffFolders(String folder1, String folder2, String resultFile) throws IOException {
List<File> files1 = Files.walk(Paths.get(folder1))
.filter(Files::isRegularFile)
.map(Path::toFile)
.collect(Collectors.toList());
List<File> files2 = Files.walk(Paths.get(folder2))
.filter(Files::isRegularFile)
.map(Path::toFile)
.collect(Collectors.toList());
Map<String, File> fileMap1 = files1.stream()
.collect(Collectors.toMap(File::getName, Function.identity()));
Map<String, File> fileMap2 = files2.stream()
.collect(Collectors.toMap(File::getName, Function.identity()));
Set<String> allNames = new HashSet<>(fileMap1.keySet());
allNames.addAll(fileMap2.keySet());
List<String> diffFiles = new ArrayList<>();
for (String name : allNames) {
File file1 = fileMap1.get(name);
File file2 = fileMap2.get(name);
if (file1 == null || !file1.isFile()) {
diffFiles.add(name + " only exists in " + folder2);
} else if (file2 == null || !file2.isFile()) {
diffFiles.add(name + " only exists in " + folder1);
} else {
Patch patch = DiffUtils.diff(new FileReader(file1), new FileReader(file2));
if (!patch.getDeltas().isEmpty()) {
diffFiles.add(name + " has differences");
}
}
}
Files.write(Paths.get(resultFile), diffFiles, StandardCharsets.UTF_8);
}
```
上述代码中,我们首先使用Files.walk()方法来遍历文件夹中的所有文件,然后使用Stream API来将其转化为File对象,并将其存放到Map中,其中键为文件名。接下来,我们将两个Map的键合并为一个集合,然后遍历每一个文件名,判断该文件是否存在于两个文件夹中,如果只存在于其中一个文件夹,则将其记录到diffFiles列表中;如果存在于两个文件夹中,则使用java-diff-utils库进行比较,如果存在差异,则同样将其记录到diffFiles列表中。最后,我们将diffFiles列表中的所有差异记录写入到resultFile文件中。
为了实现读取jar包中的文件夹,我们可以使用ClassLoader类的getResourceAsStream()方法来获取文件夹中的所有文件流。同时,我们需要将FileReader替换为InputStreamReader,如下所示:
```java
public void diffJarFolders(String folder1, String folder2, String resultFile) throws IOException {
List<InputStream> streams1 = getResourceStreams(folder1);
List<InputStream> streams2 = getResourceStreams(folder2);
Map<String, InputStream> streamMap1 = streams1.stream()
.collect(Collectors.toMap(this::getFileName, Function.identity()));
Map<String, InputStream> streamMap2 = streams2.stream()
.collect(Collectors.toMap(this::getFileName, Function.identity()));
Set<String> allNames = new HashSet<>(streamMap1.keySet());
allNames.addAll(streamMap2.keySet());
List<String> diffFiles = new ArrayList<>();
for (String name : allNames) {
InputStream stream1 = streamMap1.get(name);
InputStream stream2 = streamMap2.get(name);
if (stream1 == null) {
diffFiles.add(name + " only exists in " + folder2);
} else if (stream2 == null) {
diffFiles.add(name + " only exists in " + folder1);
} else {
Patch patch = DiffUtils.diff(new InputStreamReader(stream1), new InputStreamReader(stream2));
if (!patch.getDeltas().isEmpty()) {
diffFiles.add(name + " has differences");
}
}
}
Files.write(Paths.get(resultFile), diffFiles, StandardCharsets.UTF_8);
}
private List<InputStream> getResourceStreams(String folder) throws IOException {
List<InputStream> streams = new ArrayList<>();
ClassLoader classLoader = getClass().getClassLoader();
try (InputStream inputStream = classLoader.getResourceAsStream(folder)) {
if (inputStream == null) {
throw new FileNotFoundException("Folder " + folder + " not found in classpath");
}
try (ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
if (!zipEntry.isDirectory()) {
streams.add(zipInputStream);
}
}
}
}
return streams;
}
private String getFileName(InputStream stream) {
return new File(stream.toString()).getName();
}
```
上述代码中,我们首先使用ClassLoader类的getResourceAsStream()方法来获取jar包中的文件夹的流,然后使用ZipInputStream来解压缩该流,并获取其中的所有文件流。接下来,我们将这些文件流转化为文件名与流的映射关系的Map。然后,我们将两个Map的键合并为一个集合,遍历每一个文件名,判断该文件是否存在于两个文件夹中,如果只存在于其中一个文件夹,则将其记录到diffFiles列表中;如果存在于两个文件夹中,则使用java-diff-utils库进行比较,如果存在差异,则同样将其记录到diffFiles列表中。最后,我们将diffFiles列表中的所有差异记录写入到resultFile文件中。
这样,我们就实现了Java 8下利用java-diff-utils库,将两个文件夹下的同名大数据量文件进行对比,将是否存在、差异文件的差异数据输出到result文件中,并且支持读取jar包中的文件夹,减少嵌套循环,提高性能。
阅读全文