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

C#实现文件夹重复文件比对 进度百分比统计不准确如何解决?

问题根源
  • 总任务量统计错误:将两个文件夹的文件数之和作为进度计算的分母,但嵌套循环逻辑实际会产生M*N次重复的哈希计算操作,总操作量远大于设定的分母,导致进度计算完全失真。
  • 进度更新时机错误:进度打印逻辑只放在外层循环末尾,内层循环处理第二个文件夹文件时不会更新进度,会出现进度跳变、显示不准的问题。
  • 额外性能冗余:内层循环每次都会重复计算第一个文件夹当前文件的哈希,完全无意义,会导致执行效率随文件数量上升极速下降。
修复方案

先调整比对逻辑降低时间复杂度,再修正进度统计逻辑:

  1. 提前预计算第二个文件夹所有文件的哈希并存储到字典,避免嵌套循环
  2. 总任务量设为两个文件夹的文件总数,每完成一个文件的哈希计算就更新一次进度
  3. 进度更新时机调整为每次处理完单个文件后

修复后代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;

namespace mvp
{
    class Program
    {
        public static string ComputeHash(string filename)
        {
            using (HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"))
            {
                try
                {
                    using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
                    {
                        return BitConverter.ToString(algorithm.ComputeHash(fs)).Replace("-", "").ToLowerInvariant();
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            }
        }

        static void Main(string[] args)
        {
            int totalFiles = 0, 
                processedCount = 0,
                totalDuplicatesFound = 0;

            // 替换为实际文件夹路径
            string firstPath = @"";
            string secondPath = @"";

            DirectoryInfo firstDir = new DirectoryInfo(firstPath);
            DirectoryInfo secondDir = new DirectoryInfo(secondPath);

            List<FileInfo> FirstFolderFiles = new List<FileInfo>();
            List<FileInfo> SecondFolderFiles = new List<FileInfo>();

            Console.WriteLine("Initializing...");

            FirstFolderFiles = firstDir.GetFiles("*.*", SearchOption.AllDirectories).ToList();
            SecondFolderFiles = secondDir.GetFiles("*.*", SearchOption.AllDirectories).ToList();

            // 总任务量为两个文件夹所有文件的哈希计算任务
            totalFiles = FirstFolderFiles.Count + SecondFolderFiles.Count;
            Dictionary<string, List<FileInfo>> secondFolderHashDict = new Dictionary<string, List<FileInfo>>();

            Console.WriteLine("Scanning...");

            // 先处理第二个文件夹的所有文件,预存哈希
            foreach(FileInfo secondFile in SecondFolderFiles)
            {
                string hash = ComputeHash(secondFile.FullName);
                if (!secondFolderHashDict.ContainsKey(hash))
                {
                    secondFolderHashDict[hash] = new List<FileInfo>();
                }
                secondFolderHashDict[hash].Add(secondFile);
                processedCount++;
                int percentage = processedCount * 100 / totalFiles;
                Console.WriteLine($"Progress: {percentage} %");
            }

            // 再处理第一个文件夹的文件,直接查字典判断重复
            foreach(FileInfo firstFile in FirstFolderFiles)
            {
                string hash = ComputeHash(firstFile.FullName);
                if (secondFolderHashDict.TryGetValue(hash, out var duplicateFiles))
                {
                    totalDuplicatesFound += duplicateFiles.Count;
                }
                processedCount++;
                int percentage = processedCount * 100 / totalFiles;
                Console.WriteLine($"Progress: {percentage} %");
            }

            Console.WriteLine($"Scan completed, total duplicates found: {totalDuplicatesFound}");
        }
    }
}
修复后效果
  • 时间复杂度从O(M*N)降到O(M+N),文件数量多时性能提升百倍以上
  • 进度会随着每个文件的处理线性从0涨到100%,不会出现提前结束、跳变的问题
  • 避免了重复计算哈希的冗余操作,执行效率大幅提升

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 20:06:04