当前位置: 面试刷题>> 在系统中找到重复文件 (经典算法题500道)


题目描述补充

题目:在系统中找到重复文件

问题描述: 给定一个包含多个文件和文件夹的目录路径,你需要编写一个程序来找出该目录下所有重复的文件(即内容相同的文件,但文件名或路径可能不同)。程序需要输出每组重复文件的路径列表。注意,文件大小相同并不足以判断文件内容相同,必须实际比较文件内容。

输入

  • 一个目录路径(字符串)

输出

  • 一个字典或类似结构,键为文件内容的哈希值(用于标识重复的文件组),值为包含该文件内容的所有文件路径的列表。

示例代码

PHP 示例

<?php

function findDuplicateFiles($directory) {
    $duplicates = [];
    $fileHashes = [];

    function hashAndAddFile($filePath) use (&$fileHashes, &$duplicates) {
        $hash = hash_file('sha256', $filePath);
        if (!isset($fileHashes[$hash])) {
            $fileHashes[$hash] = [];
        }
        $fileHashes[$hash][] = $filePath;

        if (count($fileHashes[$hash]) > 1) {
            $duplicates[$hash] = $fileHashes[$hash];
        }
    }

    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS),
        RecursiveIteratorIterator::LEAVES_ONLY
    );

    foreach ($iterator as $splFileInfo) {
        if ($splFileInfo->isFile()) {
            hashAndAddFile($splFileInfo->getRealPath());
        }
    }

    return $duplicates;
}

// 示例用法
$directoryPath = "/path/to/directory";
$duplicates = findDuplicateFiles($directoryPath);
print_r($duplicates);

?>

Python 示例

import hashlib
import os
from collections import defaultdict

def find_duplicate_files(directory):
    duplicates = defaultdict(list)

    def hash_and_add_file(file_path):
        hasher = hashlib.sha256()
        with open(file_path, 'rb') as f:
            buf = f.read()
            hasher.update(buf)
        file_hash = hasher.hexdigest()
        duplicates[file_hash].append(file_path)

    for root, dirs, files in os.walk(directory):
        for file in files:
            file_path = os.path.join(root, file)
            hash_and_add_file(file_path)

    return {k: v for k, v in duplicates.items() if len(v) > 1}

# 示例用法
directory_path = "/path/to/directory"
duplicates = find_duplicate_files(directory_path)
print(duplicates)

JavaScript 示例(Node.js)

const fs = require('fs');
const crypto = require('crypto');
const path = require('path');

function findDuplicateFiles(directory) {
    const duplicates = {};

    function hashAndAddFile(filePath) {
        const hash = crypto.createHash('sha256');
        const stream = fs.createReadStream(filePath);

        stream.on('data', (chunk) => {
            hash.update(chunk);
        });

        stream.on('end', () => {
            const fileHash = hash.digest('hex');
            if (!duplicates[fileHash]) {
                duplicates[fileHash] = [];
            }
            duplicates[fileHash].push(filePath);

            if (duplicates[fileHash].length > 1) {
                console.log(`Found duplicate: ${duplicates[fileHash]}`);
            }
        });

        stream.on('error', (err) => {
            console.error(`Error reading file: ${filePath}`, err);
        });
    }

    fs.readdir(directory, { withFileTypes: true }, (err, entries) => {
        if (err) throw err;

        const files = entries.filter(entry => entry.isFile());

        files.forEach(file => {
            const filePath = path.join(directory, file.name);
            hashAndAddFile(filePath);
        });
    });

    // 注意:由于异步处理,这里不会直接返回 duplicates 对象
    // 实际使用时,可能需要通过回调函数或Promise来处理结果
}

// 示例用法(注意:这里不会直接打印结果,因为fs.readdir是异步的)
const directoryPath = "/path/to/directory";
findDuplicateFiles(directoryPath);

// 码小课网站中有更多相关内容分享给大家学习

请注意,JavaScript 示例中由于文件读取是异步的,因此直接返回 duplicates 对象并不现实。在实际应用中,你可能需要通过回调函数、Promise 或 async/await 来处理异步结果。

推荐面试题