You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

关键细节说明

  1. 路径处理:使用正斜杠/替代反斜杠\,避免Perl字符串转义问题,同时支持跨平台
  2. 哈希预计算:提前遍历目标文件夹计算所有文件哈希,避免处理每个源文件时重复遍历目标文件夹,大幅提升效率
  3. 内容校验:通过Digest::MD5以二进制模式读取文件计算哈希,确保仅对比文件内容(忽略文件名、修改时间等元数据)
  4. 复制验证:复制后重新计算哈希,避免因IO错误导致的文件损坏,确保复制内容完全一致后才删除源文件

你的测试代码存在的问题

  • 路径使用未转义的反斜杠\,Perl会将其解析为转义字符,导致路径错误
  • $destinationFolder被错误设置为文件路径,而非文件夹路径
  • 仅通过文件是否存在判断是否重复,无法确保内容一致

内容的提问来源于stack exchange,提问作者user1670137

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 04:43:22