Оптимизация I/O операций для работы с большими текстовыми файлами (1Гб+) - C#

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

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

Доброго времени суток. Подскажите каким образом можно оптимизировать I/O операций для работы с большими текстовыми файлами (1Гб+) Мне поставили задачу считывать данные из файла, делить каждую строку на слова и далее записывать список слов в другой файл с указанием номеров строк где каждое из слов встречается в файле №1. Человек давший задание предложил мне использовать другую структуру данных, чтобы оптимизировать чтение/запись. Какая из структур данных справиться с этой задачей лучше List<T>? Буду благодарен за ссылки на статьи и литературу про оптимизацию I/O для текстовых файлов. Класс представляющий слово
public class Word
    {
        public string Text { get; set; }
        public List<int> LineNumbers { get; set; }
 
        public Word()
        {
            LineNumbers = new List<int>();
        }
    }
Вот метод в котором я построчно считываю файл и создаю список слов
public List<Word> ReadFileAsync(string filePath)
        {
          //  var watch = System.Diagnostics.Stopwatch.StartNew();
 
            List<Word> words = new List<Word>();
            int lineCount = 1;
 
            try
            {
                using (StreamReader sr = new StreamReader(filePath))
                {
                    string nextLine;
                    while ((nextLine = sr.ReadLine()) != null)
                    {
                        AddWordFromLineToWordList(SplitLineIntoWords(nextLine), words, lineCount);
                        lineCount++;
                    }
                }
            }
            catch (Exception ex)
            {
            }
 
          //  watch.Stop();
          //  var elapsedMs = watch.ElapsedMilliseconds;
          // Console.WriteLine(elapsedMs);
 
            return words;
        }
Метод с помощью которого я записываю результат в другой файл
public async Task WriteAsync(string path, List<Word> words)
        {
            DeleteFile(path);
            CreateFile(path);
            words.Sort(new WordComparer());
            foreach (Word word in words)
            {
                await WriteWordsAndLineNumbersAsync(path, word);
            }
        }
private async Task WriteWordsAndLineNumbersAsync(string path, Word word)
        {
            try
            {
                using (FileStream fs = new FileStream(path, FileMode.Append,
                    FileAccess.Write, FileShare.Write, 4096, useAsync: true))
                {
                    using (StreamWriter sw = new StreamWriter(fs))
                    {
                        await sw.WriteAsync(word.Text + " ");
 
                        int size = word.LineNumbers.Count;
                        for (int i = 0; i < size; i++)
                        {
                            if (i < size - 1)
                            {
                                await sw.WriteAsync(word.LineNumbers[i] + ", ");
                            }
                            else
                            {
                                await sw.WriteAsync(word.LineNumbers[i].ToString());
                            }
                        }
                        sw.Write(Environment.NewLine);
                    }
                }
            }
            catch (Exception ex)
            {
 
            }
        }

Решение задачи: «Оптимизация I/O операций для работы с большими текстовыми файлами (1Гб+)»

textual
Листинг программы
      static void Main(string[] args)
      {
         string str = "1 The the quick, brown fox. r fox jumped over the lazy dog dog.The1 the1 quick1, brown1 fox1.  fox1 jumped1 over1 the1 lazy1 dog1 dog1.";
 
         Regex pattern = new Regex(
                @"( [A-Za-z0-9]
                ([A-Za-z0-9])*
                [A-Za-z0-9])",
                RegexOptions.IgnorePatternWhitespace);
 
         List<string> list1 = SplitLineIntoWords(str, pattern);
         List<string> list2 = SplitLineIntoWords2(str);
 
         for(int i = 0; i < list1.Count; ++i)
         {
            if(!list1[i].SequenceEqual(list2[i])) throw new Exception();
         }
 
 
         Stopwatch sw1 = Stopwatch.StartNew();
         list1 = SplitLineIntoWords(str, pattern);
         sw1.Stop();
         Console.WriteLine($"SplitLineIntoWords {sw1.ElapsedTicks}");
 
         Stopwatch sw2 = Stopwatch.StartNew();
         list2 = SplitLineIntoWords2(str);
         sw2.Stop();
         Console.WriteLine($"SplitLineIntoWords2 {sw2.ElapsedTicks}");
 
         Console.ReadKey();
         GC.KeepAlive(list1);
         GC.KeepAlive(list2);
      }
 
      public static unsafe List<string> SplitLineIntoWords2(string str)
      {
         List<string> list = new List<string>();
         int index = 0;
         bool flag = false;
         int i = 0;
         fixed (char* ptr = str)
         {
            for(i = 0; i < str.Length; ++i)
            {
               int n = ptr[i];
               if((n >= 'a' && n <= 'z') || (n >= 'A' && n <= 'Z') || (n >= '0' && n <= '9'))
               {
                  if(!flag)
                  {
                     flag = true;
                     index = i;
                  }
               }
               else
               {
                  if(flag && i - index > 1)
                  {
                     list.Add(new string(ptr, index, i - index).ToLower());
                  }
                  flag = false;
                  index = i;
               }
            }
            if(flag && i - index > 1)
            {
               list.Add(new string(ptr, index, i - index).ToLower());
            }
         }
         return list;
      }
 
      public static List<string> SplitLineIntoWords(string lineText, Regex pattern)
      {
         List<string> lineWords = new List<string>();
         foreach(Match m in pattern.Matches(lineText))
         {
            lineWords.Add(m.Groups[1].Value.ToLower());
         }
         return lineWords;
      }
   }

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


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

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

11   голосов , оценка 4.364 из 5
Похожие ответы