功能介绍:在传入Windows路径后(例如“D:\小米云服务下载”),遍历文件夹下所视频有文件(包括子文件夹下的视频文件,其他类型不做判断),判断视频文件是否重复(由于视频文件很大,无法计算整个文件的哈希值,所以对文件大于5MB的文件,仅判断前5MB的哈希值),如果重复则列出所有重复文件的文件大小(以MB为单位,并保留两位小数)和绝对路径。
使用了MD5算法,虽然通常情况下足够用于检测文件重复,但在某些场景下MD5可能不是最安全的选择。如果你的应用场景对安全性要求较高,则应考虑使用更安全的哈希算法如SHA-256等。
// 该程序定义了一个Main类,其中包含一个主方法用于启动程序,并定义了一个辅助方法来查找重复的视频文件。这个程序使用了Java NIO来处理文件路径,并利用了MessageDigest来计算文件开头部分的哈希值。
// 实际部署此代码时需要考虑异常处理、资源管理(如关闭流)以及性能优化等方面.
import java.io.*;
import java.nio.file.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.util.*;
public class Main {
public static void main(String[] args) {
String pathStr = "D:\\\\小米云服务下载";
File rootDir = new File(pathStr);
if (!rootDir.exists() || !rootDir.isDirectory()) {
System.out.println("Path does not exist or is not a directory.");
return;
}
Map<String, List<File>> videoMap = new HashMap<>();
findDuplicateVideos(rootDir, videoMap);
// 输出重复的视频文件信息
DecimalFormat df = new DecimalFormat("#.00"); // 保留两位小数
for (List<File> fileList : videoMap.values()) {
if (fileList.size() > 1) {
System.out.println("Duplicates found:");
for (File file : fileList) {
double sizeInMB = file.length() / (1024.0 * 1024.0); // 转换为MB
System.out.println("Size: " + df.format(sizeInMB) + " MB, Path: " + file.getAbsolutePath());
}
}
}
}
private static void findDuplicateVideos(File dir, Map<String, List<File>> videoMap) {
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
// 递归处理子目录
findDuplicateVideos(file, videoMap);
} else if (isVideoFile(file) && file.length() > 5 * 1024 * 1024) { // 检查文件是否大于5MB
try {
// 只读取前5MB的数据
byte[] buffer = new byte[5 * 1024 * 1024];
FileInputStream fis = new FileInputStream(file);
int read = fis.read(buffer);
fis.close();
// 计算哈希值
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(buffer, 0, read);
String hash = bytesToHex(md.digest());
// 收集具有相同哈希值的文件
videoMap.computeIfAbsent(hash, k -> new ArrayList<>()).add(file);
} catch (IOException | NoSuchAlgorithmException e) {
System.err.println("Error processing file: " + file.getAbsolutePath());
}
}
}
}
}
private static boolean isVideoFile(File file) {
// 这里简单地通过文件扩展名判断是否为视频文件
String name = file.getName().toLowerCase();
return name.endsWith(".mp4") || name.endsWith(".avi") || name.endsWith(".mkv")
|| name.endsWith(".flv") || name.endsWith(".wmv") || name.endsWith(".mov");
}
private static String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
}