这是一个使用 Java NIO 包的简单迭代解决方案(不使用访问者模式,因此它也可以适用于早期的 Java 版本)。
当然可以对其进行调整,但目前这是一个简单的解决方案,可以从两个目录的视图中检查每个文件是否出现,并可选择使用 Apache Commons FileUtils 比较文件内容。
/**
* checks if the directory file lists and file content is equal
*
* @param directory
* the directory
* @param compareDirectory
* the directory to compare with
* @param checkFileContent
* also compare file content
* @return true if directory and compareDirectory are equal
* @throws IOException
*/
public static boolean isEqualDirectories(Path directory, Path compareDirectory, boolean checkFileContent) throws IOException {
boolean check = isEverythingInCompareDirectory(directory, compareDirectory, checkFileContent);
boolean checkOpposite = check && isEverythingInCompareDirectory(directory, compareDirectory, checkFileContent);
return check && checkOpposite;
}
/**
* checks if the directory file lists and file content is equal
*
* @param directory
* the directory
* @param compareDirectory
* the directory to compare with
* @param checkFileContent
* also compare file content
* @return true if directory and compareDirectory are equal
* @throws IOException
*/
public static boolean isEverythingInCompareDirectory(Path directory, Path compareDirectory, boolean checkFileContent)
throws IOException {
try {
LOGGER.info("checking directory " + directory);
File directoryFile = directory.toFile();
File compareFile = compareDirectory.toFile();
// check, if there is the same number of files/subdirectories
File[] directoryFiles = directoryFile.listFiles();
File[] compareFiles = compareFile.listFiles();
if (directoryFiles.length == compareFiles.length) {
return compareDirectoryContents(directory, compareDirectory, checkFileContent);
} else {
LOGGER.info("number of files in directory are different " + directoryFiles.length + " vs compareDirectory: " + compareFiles.length);
return false;
}
} catch (IOException e) {
throw new RuntimeException("Failed to assert that all files are equal", e);
}
}
public static boolean compareDirectoryContents(Path directory, Path compareDirectory, boolean checkFileContent) throws IOException {
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(directory)) {
for (Path directoryFilePath : directoryStream) {
// search for directoryFile in the compareDirectory
Path compareFilePath = compareDirectory.resolve(directoryFilePath.getFileName());
if (compareFilePath != null) {
File directoryFile = directoryFilePath.toFile();
if (directoryFile.isFile()) {
LOGGER.info("checking file " + directoryFilePath);
if (checkFileContent && !FileUtils.contentEquals(compareFilePath.toFile(), directoryFile)) {
LOGGER.info("files not equal: compare: " + compareFilePath.toFile() + ", directory: " + directoryFilePath.getFileName() + "!");
return false;
}
} else {
LOGGER.info("going into recursion with directory " + directoryFilePath);
boolean result = isEverythingInCompareDirectory(directoryFilePath, compareFilePath, checkFileContent);
// cancel if not equal, otherwise continue processing
if (!result) {
return false;
}
}
} else {
LOGGER.info(directoryFilePath.toString() + ": compareFilepath not found");
return false;
}
}
}
return true;
}