Perl开发:按MD5哈希判断重复文件并处理源文件的需求实现
Perl实现基于哈希校验的文件移动去重功能
核心实现思路
遍历源文件夹内所有文件,通过计算文件内容的MD5哈希值判断目标文件夹是否存在完全重复的文件:
- 若存在内容完全匹配的文件,直接删除源文件
- 若不存在,将源文件复制到目标文件夹,验证复制内容无误后删除源文件
完整代码实现
use strict; use warnings; use File::Find; use Digest::MD5; use File::Copy; use File::Basename; # 配置源文件夹与目标文件夹路径(推荐用正斜杠,跨平台兼容) my $source_dir = 'H:/New Folder'; my $dest_dir = 'I:/New Folder'; # 预计算目标文件夹所有文件的哈希值,避免重复计算提升效率 my %dest_file_hashes; find(sub { return if -d $_; # 跳过子目录 my $file_path = $File::Find::name; my $hash = compute_file_hash($file_path); $dest_file_hashes{$hash} = 1 if defined $hash; }, $dest_dir); # 遍历处理源文件夹中的每个文件 find(sub { return if -d $_; # 跳过子目录 my $source_file = $File::Find::name; my $file_name = basename($source_file); my $dest_file = "$dest_dir/$file_name"; # 计算源文件的MD5哈希 my $source_hash = compute_file_hash($source_file); unless (defined $source_hash) { warn "无法计算文件 $source_file 的哈希值,跳过处理\n"; return; } # 检查目标文件夹是否存在内容重复的文件 if (exists $dest_file_hashes{$source_hash}) { print "发现重复文件(哈希匹配):$source_file,直接删除\n"; unlink $source_file or warn "删除 $source_file 失败:$!\n"; } else { # 复制文件到目标文件夹 print "复制文件:$source_file -> $dest_file\n"; copy($source_file, $dest_file) or do { warn "复制 $source_file 失败:$!\n"; return; }; # 验证复制后的文件内容是否一致 my $copied_hash = compute_file_hash($dest_file); if ($copied_hash eq $source_hash) { print "复制验证通过,删除源文件:$source_file\n"; unlink $source_file or warn "删除 $source_file 失败:$!\n"; # 将新文件哈希加入表,供后续文件匹配使用 $dest_file_hashes{$source_hash} = 1; } else { warn "复制后的文件哈希不匹配,保留源文件并删除损坏副本\n"; unlink $dest_file or warn "删除损坏副本 $dest_file 失败:$!\n"; } } }, $source_dir); # 计算文件MD5哈希的工具函数 sub compute_file_hash { my ($file_path) = @_; open my $fh, '<:raw', $file_path or do { warn "打开文件 $file_path 失败:$!\n"; return undef; }; my $md5 = Digest::MD5->new; $md5->addfile($fh); close $fh; return $md5->hexdigest; }
关键细节说明
- 路径处理:使用正斜杠
/替代反斜杠\,避免Perl字符串转义问题,同时支持跨平台 - 哈希预计算:提前遍历目标文件夹计算所有文件哈希,避免处理每个源文件时重复遍历目标文件夹,大幅提升效率
- 内容校验:通过
Digest::MD5以二进制模式读取文件计算哈希,确保仅对比文件内容(忽略文件名、修改时间等元数据) - 复制验证:复制后重新计算哈希,避免因IO错误导致的文件损坏,确保复制内容完全一致后才删除源文件
你的测试代码存在的问题
- 路径使用未转义的反斜杠
\,Perl会将其解析为转义字符,导致路径错误 $destinationFolder被错误设置为文件路径,而非文件夹路径- 仅通过文件是否存在判断是否重复,无法确保内容一致
内容的提问来源于stack exchange,提问作者user1670137
相关产品推荐
相关产品推荐

