функция контрольной суммы файла c #

#c# #list #dictionary

#c# #Список #словарь

Вопрос:

Я создаю эту функцию, чтобы проверить, все ли мои файлы по-прежнему верны или некоторые файлы отсутствуют.

До сих пор мне удалось получить список с файлами из корневого каталога и другой список со всеми его хэшами.

Мне также удалось создать исправный текстовый файл с хэшем. который содержит хэш-3 вкладки (чтобы его было легче читать в блокноте), а затем имя файла из корня.

например.

 3914ea0985f3f67a8204685beb6d1be6            file1.extension
2ed432f68ab6ebfc32664409482f0de2            folder1file2.extension
  

Каждый из них попадает в отдельный список, так что теперь у меня есть 4 списка.

Мне было интересно, следует ли мне использовать словари вместо этого, чтобы сократить 4 списка до 2 словарей.

Таким образом, имя файла (плюс любой подкаталог) будет ключом, а значение будет хэшем.

 KEY                                 VALUE
file1.extension                    3914ea0985f3f67a8204685beb6d1be6
folder1file2.extension            2ed432f68ab6ebfc32664409482f0de2
  

Я предполагаю, что, делая это, я могу проверить наличие отсутствующих файлов и удалить эти ключи из словаря с исправными хэшами. Чтобы я мог одинаково сравнивать существующие файлы друг с другом. (только на основе индекса).

Ниже приведены мои текущие коды для получения необходимого материала.

Это возвращает список файлов:

     public List<string> Get_FileList(string root)
    {
        List<string> FileList = Directory.GetFiles(root, "*.*", SearchOption.AllDirectories).Where(name => 
        { 
            return
                !(name.EndsWith("dmp") || name.EndsWith("jpg") ||                               //exclude dmp and image files
                name.EndsWith("FileChecker.exe"));                                             //exclude myself
        }).ToList();

        return FileList;
    }
  

Это возвращает хэши:

     public List<string> Get_FileHash(List<string> FileList)
    {
        List<string> FileHash = new List<string>();
        foreach (string FileName in FileList)
        {
            FileStream file = new FileStream(FileName, FileMode.Open, FileAccess.Read);
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] retVal = md5.ComputeHash(file);
            file.Close();

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < retVal.Length; i  )
            {
                sb.Append(retVal[i].ToString("x2"));
            }
            FileHash.Add(sb.ToString());
        }
        return FileHash;
    }
  

Это позволяет получить исправные хэши:

 public void Get_HealthyHash(string file, out List<string> Healthy_FileList, out List<string> Healthy_HashList) 
    {
        string resource= "FileCheckSum.Resources."   file;

        Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource);

        StreamReader reader = new StreamReader(stream);

        Healthy_FileList = new List<string>();
        Healthy_HashList = new List<string>();

        string line;
        while ((line = reader.ReadLine()) != null)
        {
            string[] items = line.Split(new string[] { "ttt" }, StringSplitOptions.RemoveEmptyEntries);
            Healthy_FileList.Add(items[1]);
            Healthy_HashList.Add(items[0]);
        }

    }
  

И для определения отсутствующих файлов я использую это:

 IEnumerable<string> Dif_File_list = Healthy_FileList.Except(FileList.Select(name => name.Replace(root, "")));
  

Я должен удалить корень здесь, поскольку у исправного хэш-файла нет пути из C:

Итак, вы можете увидеть 4 списка (ну, 5 после получения различий).

Мой вопрос:

Как я могу / должен продолжить проверку существующих файлов, если они действительны с этого момента? без вмешательства отсутствующих файлов.

Буду признателен за любую помощь, улучшение моих функций или указателей для продолжения. ОБРАТИТЕ ВНИМАНИЕ, что весь приведенный здесь код работает! Будь это медленно с большим количеством файлов, поскольку я не добавил никаких потоков, чтобы ускорить его.

Комментарии:

1. Ваш код можно было бы немного очистить и упростить, но это происходит медленно только потому, что вы (должны) использовать md5.ComputeHash(file) . Это не изменится.

2. Да, я знаю об очистке, это всего лишь приблизительная версия. есть ли альтернатива, чтобы сделать это быстрее? в настоящее время для вычисления всех хэшей требуется около 30-35 секунд.

3. Но все же мне следует использовать словари или нет? чтобы хэш, принадлежащий файлу X, не перепутался с хэшем файла Y.

4. Словари или кортежи… Вы пропустили потребляющую часть. Есть специальный сайт для обзоров кода.

5. На самом деле речь идет не о проверке кода, а о том, как действовать, откуда. У меня есть, скажем, 1000 исправных хэшей (из 1000 файлов соответственно). Я хочу сравнить его с файлами из текущего корня, но присутствуют только 995 файлов (отсутствуют 5 случайных файлов, таким образом, на 5 хэшей меньше для проверки). Следовательно, мой вопрос: облегчат ли словари мою проблему? Как эффективно проверять файлы без вмешательства отсутствующих файлов?

Ответ №1:

Создайте класс объектов MyFileInfo со строковыми свойствами FileName и hashValue. Реализовать IEqualityComparer, переопределить методы Equals и GetHashCode.

Затем загрузите исправный список<MyFileInfo> из файла и создайте для проверки список< MyFileInfo> из текущего каталога.

Используйте методы LINQ, чтобы найти различия между списками.

Посмотрите здесь LINQ Distinct, Except, Contains, Union, Intersect и IEqualityComparer