.NET 3.x OutOfMemoryException при получении большого количества файлов из каталога - C#

Узнай цену своей работы

Формулировка задачи:

Доброго времени суток. Есть программа, которая в виде аргумента получает директорию, в которой она ищет и сравнивает все файлы и во всех поддиректориях. Проблема в том, что она слишком много жрет(30-40% ЦП и 400Мб ОЗУ, но так не всегда, это критические моменты). И если количество файлов уж очень большое(около 7к+) то вылетает выше написанное исключение. Могли бы вы подкинуть инфы об оптимизации кода на С#?

Решение задачи: «.NET 3.x OutOfMemoryException при получении большого количества файлов из каталога»

textual
Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4.  
  5. namespace Compare
  6. {
  7.     class myCompareFile
  8.     {
  9.         List<EqualFile> output = new List<EqualFile>();
  10.         List<File> AllFiles = new List<File>();
  11.        
  12.         public List<EqualFile> CompareFile(string path)
  13.         {
  14.             // список файлов в этой директории
  15.             List<string> files = new List<string>();
  16.             // список папок в этой директории
  17.             List<string> dirs = new List<string>();
  18.  
  19.             /*Шукаєм всі доступні файли*/
  20.             try
  21.             {
  22.                 /*Добавляю знайдені папки і файли в список*/
  23.                 files.AddRange(Directory.GetFiles(path));
  24.                 dirs.AddRange(Directory.GetDirectories(path));
  25.             }
  26.             catch (UnauthorizedAccessException ex)
  27.             {
  28.                 Console.WriteLine(ex.Message);
  29.             }
  30.             catch (DirectoryNotFoundException ex)
  31.             {
  32.                 Console.WriteLine(ex.Message);
  33.             }
  34.  
  35.             // перебираем все новые файлы
  36.             foreach (var newFile in files)
  37.             {
  38.                 // получаем совпадения текущего файла с уже имеющимися в списке
  39.                 List<string> fromAll = CompareLength(newFile);
  40.                 if (fromAll.Count != 0) // если что-то там совпало...
  41.                     foreach (var item2 in fromAll)
  42.                         if (CompareHash(newFile, item2)) // то сравним хеши (ТС сравнит :)
  43.                             output.Add(new EqualFile(newFile, item2)); // если совпали хеши, то добавим в совпадения
  44.                 AllFiles.Add(new File(newFile, new FileInfo(newFile).Length)); // добавляем текущий файл ко всем
  45.             }
  46.  
  47.             /*"Заглядаєм" за файлами в кожну директорію...*/
  48.             foreach (string dir in dirs)
  49.             {
  50.                 // прогуливаемся по директориям дальше
  51.                 CompareFile(dir);
  52.             }
  53.  
  54.             return output;
  55.         }
  56.  
  57.         /// <summary>
  58.         /// Сравнивает по длинне текущий файл с имеющимеся в списке
  59.         /// </summary>
  60.         /// <param name="file"></param>
  61.         /// <returns></returns>
  62.         private List<string> CompareLength(string file)
  63.         {
  64.             List<string> result = new List<string>();
  65.             foreach (var item in AllFiles)
  66.                 if (item.Length == new FileInfo(file).Length)
  67.                     result.Add(item.Path);
  68.             return result;
  69.         }
  70.  
  71.         /// <summary>
  72.         /// Должна сравнивать файлы по хешу
  73.         /// </summary>
  74.         /// <param name="file1"></param>
  75.         /// <param name="file2"></param>
  76.         /// <returns>true если совпали</returns>
  77.         private bool CompareHash(string file1, string file2)
  78.         {
  79.             int sizeBlock = 16;
  80.  
  81.             char[] buffer1 = new char[sizeBlock];
  82.             char[] buffer2 = new char[sizeBlock];
  83.  
  84.             using (StreamReader sr1 = new StreamReader(file1), sr2 = new StreamReader(file2))
  85.             {
  86.                 // предполагаю, если размеры файлов одинаковые,
  87.                 // то нет смысла проверять на конец sr1 и sr2
  88.                 long size = new FileInfo(file1).Length;
  89.                 for (int i = 0; i < size; i += sizeBlock)
  90.                 {
  91.                     try
  92.                     {
  93.                         sr1.ReadBlock(buffer1, i, sizeBlock);
  94.                         sr2.ReadBlock(buffer2, i, sizeBlock);
  95.                     }
  96.                     catch (Exception ex)
  97.                     {
  98.                         Console.WriteLine("Error: {0}", ex.Message);
  99.                     }
  100.  
  101.                     // здесь должны сравниваться хеши, но это уже сделает автор :)
  102.                     for (int j = 0; j < buffer1.Length; ++j)
  103.                         if (buffer1[j] != buffer2[j])
  104.                             return false;
  105.  
  106.                     if (size - i < sizeBlock)
  107.                         sizeBlock = (int)(size - i);
  108.                 }
  109.             }
  110.  
  111.             return true;
  112.         }
  113.     }
  114.  
  115.     /// <summary>
  116.     /// представляет класс файла.
  117.     /// </summary>
  118.     class File
  119.     {
  120.         public File() { }
  121.  
  122.         public File(string path, long length)
  123.         {
  124.             Path = path;
  125.             Length = length;
  126.         }
  127.  
  128.         public long Length { get; set; }
  129.         public string Path { get; set; }
  130.  
  131.         public override string ToString()
  132.         {
  133.             return Path + "; Length = " + Length;
  134.         }
  135.     }
  136.  
  137.     /// <summary>
  138.     /// класс для совпавших файлов
  139.     /// тупо для удобства, можно заменить
  140.     /// </summary>
  141.     public class EqualFile
  142.     {
  143.         public EqualFile() { }
  144.         public EqualFile(string file1, string file2)
  145.         {
  146.             File1 = file1;
  147.             File2 = file2;
  148.         }
  149.  
  150.         public string File1 { get; set;}
  151.         public string File2 {get; set;}
  152.  
  153.         public override string ToString()
  154.         {
  155.             return File1 + " ===== " + File2;
  156.         }
  157.     }
  158.  
  159.     public class superMain
  160.     {
  161.         public static void Main()
  162.         {
  163.             myCompareFile mcf = new myCompareFile();
  164.             List<EqualFile> path = mcf.CompareFile("D:\\obraz\\");
  165.             foreach (var file in path)
  166.                 Console.WriteLine(file);
  167.             Console.ReadLine();
  168.         }
  169.     }
  170. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 4.143 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы