2013-04-11 2 views
4

Мне было предложено создать метод, который будет читать в очень больших текстовых файлах в программу, эти файлы могут варьироваться от 2 до 100 гб.Чтение очень больших текстовых файлов, следует ли включать async?

Идея до сих пор заключалась в том, чтобы прочитать несколько тысяч строк текста в методе.

В настоящий момент программа настроена с использованием считывателя потока, который читает файл по строкам и обрабатывает необходимые области данных, найденных на этой линии.

using (StreamReader reader = new StreamReader("FileName")) 
{ 
    string nextline = reader.ReadLine(); 
    string textline = null; 

    while (nextline != null) 
    { 
     textline = nextline; 
     Row rw = new Row(); 
     var property = from matchID in xmldata 
         from matching in matchID.MyProperty 
         where matchID.ID == textline.Substring(0, 3).TrimEnd() 
         select matching; 

     string IDD = textline.Substring(0, 3).TrimEnd(); 

     foreach (var field in property) 
     { 
      Field fl = new Field(); 

      fl.Name = field.name; 
      fl.Data = textline.Substring(field.startByte - 1, field.length).TrimEnd(); 
      fl.Order = order; 
      fl.Show = true; 

      order++; 

      rw.ID = IDD; 
      rw.AddField(fl); 
     } 
     rec.Rows.Add(rw); 
     nextline = reader.ReadLine(); 

     if ((nextline == null) || (NewPack == nextline.Substring(0, 3).TrimEnd())) 
     { 
      d.ID = IDs.ToString(); 
      d.Records.Add(rec); 
      IDs++; 
      DataList.Add(d.ID, d); 
      rec = new Record(); 

      d = new Data(); 
     } 
    } 
} 

Программа продолжается и заполняет класс. (просто решил не оставлять остальное)

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

, так что это моя текущая проблема, и до сих пор я искал несколько подходов, многие люди просто отвечали на использование чтения и чтения потоков. Readtoend, я знаю, что readtoend не будет работать для меня, поскольку я получу эти ошибки памяти.

Наконец, я изучал async как способ создания метода, который будет читать определенное количество строк и ждать вызова до обработки следующего количества строк.

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

Конечно, если кто-нибудь знает, как лучше решить эту проблему, я все уши.

EDIT Добавлен остаток кода, чтобы положить конец любой путанице.

+4

Я не вижу никакой необходимости в асинхронности здесь. Похоже, вам нужно передавать данные, но можете обрабатывать их полностью синхронно. – Servy

+1

Где происходят исключения памяти (какая строка)? Как вы читаете следующую строку? Что такое xmldata? Как долго длится каждая строка в файле? – Polyfun

+0

Если вы используете .NET 4.0, библиотека задач - отличный способ управлять асинхронными потоками. BlockingCollection - отличный способ справиться с ситуацией с производителем, которую вы могли бы использовать в этом случае. Прочитайте некоторые данные из потока и добавьте их в очередь, затем выполните одну из следующих потоков, обрабатывающих эту очередь. – cgotberg

ответ

6

Ваша проблема не является асинхронным синхронной Ви, это то, что вы читаете весь файл и хранения части файла в памяти, прежде чем сделать что-то с этими данными.

Если вы читали каждую строку, обрабатывали ее и записывали результат в другой файл/базу данных, то StreamReader позволит вам обрабатывать файлы с несколькими GB (или TB).

Theres только проблема, если вы храните части файла до тех пор, пока не закончите читать, то вы можете столкнуться с проблемами памяти (но вы будете удивлены, насколько велики вы можете позволить Lists & Dictionaries получить перед запуском из памяти)

Что вам нужно сделать, это сохранить обработанные данные, как только сможете, и не хранить их в памяти (или хранить как можно меньше в памяти).

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

Надеюсь, что это поможет, не стесняйтесь задавать дополнительные вопросы в комментариях или редактировать исходный вопрос, я обновлю этот ответ, если смогу помочь в любом случае.

Update - Paging/Чанкинг

Вам нужно прочитать текстовый файл в куски одной страницы, и позволяют пользователю прокручивать «страницы» в файле. Когда пользователь прокручивает, вы читаете и представляете их на следующей странице.

Теперь вы можете сделать несколько вещей, чтобы помочь себе, всегда хранить около 10 страниц в памяти, это позволяет вашему приложению быть отзывчивым, если пользователь страницы вверх или вниз на несколько страниц очень быстро. В простаивании приложений (событие Idle приложения) вы можете читать на следующих нескольких страницах, снова вы удаляете страницы, которые содержат более пяти страниц до или после текущей страницы.

Пейджинг назад - проблема, потому что вы не знаете, где каждая строка начинается или заканчивается в файле, поэтому вы не знаете, где каждая страница начинается или заканчивается. Таким образом, для прокрутки назад, когда вы просматриваете файл, сохраняйте список смещений до начала каждой страницы (Stream.Pos), затем вы можете быстро отправить Seek в данную позицию и прочитать страницу оттуда.

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

Вы можете ускорить процесс предварительной обработки файла в базе данных, есть элементы управления сеткой, которые будут работать с динамическим набором данных (они будут выполнять подкачку для вас), и вы получите преимущество встроенных поисков/фильтров ,

Таким образом, из определенной точки зрения, это чтение файла асинхронно, но это с точки зрения пользователя. Но с технической точки зрения мы склонны понимать что-то еще, когда мы говорим о том, чтобы делать что-то асинхронное при программировании.

+0

hmm Я думал, что обрабатываю данные после каждой строки, сохраняя их в словаре, но я понимаю, что я получу проблемы с памятью, когда я читаю весь документ по строке, добавляя в словарь (в конце концов, я считаю, колпачок памяти). Причина, по которой я пришел к идее попробовать async, - это подождать, пока пользователь скажет стрелку вниз в пользовательском интерфейсе и обработает следующую цепочку строк. – user2169674

+1

Чувак, мне нужно будет узнать больше о проблеме, которую вы пытаетесь решить. Вы «обрабатываете» данные, затем сохраняете их, или это отображает информацию для пользователя? Если вы в основном предоставляете пользователю «представление» файла, вам необходимо прочитать файл в кусках (или страницах), когда пользователь хочет их просмотреть. Можете ли вы сказать мне, что вам нужно сделать, тогда я могу обновить свой ответ (стр. Я видел код, который вы добавили в свой вопрос, который не говорит мне, что вам нужно **). –

+0

моей задачей является разработка системы, которая будет принимать гигантские текстовые файлы, и программа предоставит им более читаемое представление файла, взяв конкретную информацию и отображая ее на экране. В настоящее время моя программа проходит через каждую строку файла до конца и берет необходимые данные, сохраняя каждую нужную часть в словаре. Надеюсь, что это очистит – user2169674

Смежные вопросы