#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