#重复文件 #文件内容 #文件搜索 #重复 #文件元数据 #重复文件查找器

dupefinder

一个支持目录递归、多个目录和特定文件重复查找的重复文件查找工具库

3 个不稳定版本

0.2.0 2024年1月1日
0.1.1 2023年12月30日
0.1.0 2023年12月30日

#666 in 文件系统

每月下载 23

MIT 许可证

45KB
730

Rust

重复文件查找器

dupefinder 是一个在一系列文件夹内查找重复文件的实用工具。每个文件夹的内容都会与其他提供的文件夹进行评估。这意味着如果文件夹 'one' 中的文件 'a.jpg' 也以 'b.jpg' 的形式存在于文件夹 'two' 中,则将其视为匹配。

该实用工具通过解析提供的文件夹中的文件元数据并按字节大小将所有文件分组在一起来工作。一旦找到具有多个文件条目的相同大小,将通过 XXH3 / xxHash 对文件内容进行哈希处理,并将其与其他相同大小文件的哈希值进行比较。

如果只找到特定大小的单个文件,则不会读取该文件并跳过。这会读取整个文件内容从磁盘生成哈希值。

哈希处理使用 BufReader 逐增量读取大文件,这应该可以防止一次将整个文件读入内存以生成哈希值。

如果找到匹配的哈希值,则找到了重复文件,并将返回。

可以通过在单个 DupeChecker 上多次运行匹配来在单个 .run() 上运行匹配,这将对所有文件夹进行全面重新检查,假设文件内容可能已更改,而不仅仅是文件的存在。

匹配会主动跳过(继续)过去的问题。当出现此类问题时,会通过 log crate 发出警告,但通常不会报告。由于支持多个目录和大量文件,因此不希望停止在特定错误上。

还有一个额外的 .run_for_file() 模式,它只会搜索特定文件的重复文件。

安装

cargo添加 dupefinder

https://crates.io/crates/dupefinder

文档

https://docs.rs/dupefinder/latest/dupefinder/

示例

非递归

let directories = vec![String::from("./resources")];
let mut checker = dupefinder::DupeFinder::new(directories);
let results = checker.run();
for key in results.keys() {
    let result = results.get(key);
    if let Some(details) = result {
        println!("{} files of size {} bytes found with hash {}", details.files.len(), details.size, details.hash);
        for file in details.files.iter() {
            println!("{}", file);
        }
    }
}
let directories = vec![String::from("./resources")];
let mut checker = dupefinder::DupeFinder::new_recursive(directories);
let results = checker.run();

for key in results.keys() {
    let result = results.get(key);
    if let Some(details) = result {
        println!("{} files of size {} bytes found with hash {}", details.files.len(), details.size, details.hash);
        for file in details.files.iter() {
            println!("{}", file);
        }
    }
}
let directories = vec![String::from("./resources")];
let mut checker = dupefinder::DupeFinder::new(directories);
let results = checker.run_for_file(String::from("./test.txt"));

if let Ok(results) = results {
    match results {
       Some(duplicate) => {
           println!("{} files found", duplicate.files.len());
        },
       None => {
           println!("no matching files found");
       },
    }
};

依赖项

~185KB