Открыть текстовый файл размером в 3 Гб

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

resident
энтузиаст
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Открыть текстовый файл размером в 3 Гб

Сообщение resident »

Здравствуйте!

Появилась такая задача, нужно открыть текстовый файл в несколько гектар, полазить по нему и кое что там изменить, перегнать из кодировки windows в UTF.

Мелкие в сотни метров спокойно грузятся в TStringList.
Но сейчас прога подвисает и срабатывает исключение.

Подскажите, как такое вобще провернуть?

з.ы. Может ли размер оперативки исправить ситуацию? (Сейчас 4 гектара оперативки и столько же подкачки. Ставил подкачку в 16 гектар, ничего не изменилось.)
з.з.ы. EmEditor спокойно файл открывает
Аватара пользователя
Sharfik
энтузиаст
Сообщения: 839
Зарегистрирован: 20.07.2013 01:04:30

Сообщение Sharfik »

Программа и ОС 32х разрядная или 64х? 32х разрядная программа не потянет за раз такое.
Насколько я помню тип данных String ограничен размером в 2 с чем то Гб, а TStringList жанглирует этим типом.

Если у тебя только перегнать задача, то может стоит функциями побайтового чтения файла читать скажем по 1Мб..100Мб в буферную строку, конвертировать и записывать в результирующий итоговый файл?
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Я такие файлы открывал с помощью TextFile и построчным считыванием ReadLn().
Аватара пользователя
Vapaamies
постоялец
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vapaamies »

resident писал(а):Мелкие в сотни метров спокойно грузятся в TStringList.
Но сейчас прога подвисает и срабатывает исключение.

Выходом, думаю, будет написанная вручную загрузка из файла в StringList через скользящий буфер. Через ReadLn -- она и есть, только размер буфера уж очень маленький.

Вместо скользящего буфера еще отображение на память можно попробовать, особенно в 64-битной ОС.
Ism
энтузиаст
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Сообщение Ism »

Есть TStringStream, очень быстрая вещь, если заранее выделять нужную память через SetSize
http://lazarus-ccr.sourceforge.net/docs ... tream.html
http://www.gunsmoker.ru/2011/11/blog-post_12.html
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

Ужос...
Технологии построчной работы с файлами утрачены напрочь и даже не вспоминаются (намёка Vadim'a никто не понял). Маниакальная привязанность считать все сразу в память упирается в категорическое незнание матчасти, в частности того, что на 32-битной windows под пользовательские данные процесса отводится не более 2 Гб и все остальное - танцы с бубнами.
Коллеги, вы что, реально считаете, что если такой файл прочесть сразу в память и ковыряться уже в ней, то это ускорит работу? Ну-ну.
resident
энтузиаст
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Сообщение resident »

Спасиб за ответы. Пока остановился на варианте:
Vadim писал(а):TextFile и построчным считыванием ReadLn()

Скорость устраивает (пробегает весь файл без какой-либо обработки за 45 секунд).

Vapaamies писал(а):Выходом, думаю, будет написанная вручную загрузка из файла в StringList через скользящий буфер.

Все к этому идет, вы знали :)

Sharfik писал(а):Программа и ОС 32х разрядная или 64х? 32х разрядная программа не потянет за раз такое.

Пересобрал 64-битный ехе, тоже виснет. Все сразу грузить похоже не вариант, потому что непонятно все напрочь зависло или еще есть шанс, что доделает.
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

resident писал(а):Все сразу грузить похоже не вариант


Не вариант.
Кроме элементарной нехватки памяти на строки можно элементарно перегрузить индексатор StringList'a (при таком размере файла количество строк непредстказуемо) или саму систему управления динамическими массивами.
stanilar
постоялец
Сообщения: 289
Зарегистрирован: 09.03.2010 18:09:02

Сообщение stanilar »

resident писал(а):Подскажите, как такое вобще провернуть?


Под виндой есть такое понятие как Memory Mapped File, под делфей для этой технологии есть куча компонент, лично у меня есть даже раализация буфера TDataSet, он на этой технологии теперь спокойно 20-30 гиг за раз ест.

Думаю, под линух есть аналог, но не знаю как он называется...

З.Ы. Если задача - перегнать, может сразу а БД? Уверен, сторонних компонент под такую задачу будет навалом.

З.З.Ы И, кстати, винда умеет работать с файлами как с БД, погуглите microsoft jet database engine file connection string. У Марко, в его небезизвестной книге, подробно написано как с ним работать.
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

stanilar
Зачем простую задачу делать сложной?
работа с текстовыми файлами - это тривиальный readln(f)
stanilar
постоялец
Сообщения: 289
Зарегистрирован: 09.03.2010 18:09:02

Сообщение stanilar »

alexs писал(а):тривиальный readln(f)


А разве readln не deprecated?

alexs писал(а):Зачем простую задачу делать сложной


За readln обычно идет дальнейшая работа, и эту работу проще и удобнее делать стандартными приемами. ReadStream умеют почти все компоненты, readfile умеют тоже, но это будет аналог полного считывания файла в память, поэтому и нужен кастомный TStream.

Если начать работать с файлом, как с БД, из коробки будет доступ к огромному множеству компонент, интерфейсную часть программы можно будет накликать мышкой. И это очень удобно, ради этого даже стоит писать свой TDataSet для чтения файла (если никак не найти сторонний, уверен что таких навалом, даже с возможностью чтения "окном").

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

P.S. Я бы выбрал или jet engine, или TDataSet.
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

stanilar
Использование DB компонент подразумевает что задача обработки текстового файла - часть какого-то постоянного процесса. И это уже явное нарушение логики разработки.
Текстовый файл - это максимиум - обмен данными между приложениями.
Во всех остальных случаях - используйте форматированные данные.
Если у вас задача обработки данных - используйте нормальную СУБД.
stanilar писал(а):А разве readln не deprecated?

Это стандартная паскальная функция - зачем ей устаревать?

Добавлено спустя 47 секунд:
ЗЫ
Микроскопом можно гвозди забивать - я знаю.
Но как-то это ... неудобно...
PapaNT
постоялец
Сообщения: 167
Зарегистрирован: 11.09.2009 12:06:46
Откуда: Москва

Сообщение PapaNT »

Полностью согласен с авторами указывавшими на readln. Прекрасная функция для последовательного чтения файлов. Только не забудьте объявить файл как текстовый:

Код: Выделить всё

Var
  t : text;

а дальше стандартные assign и restet с writeln.

Сам такими методами парсил за минуты гигабайтные файлы. Все получалось даже очень шустро :D
Аватара пользователя
DYUMON
постоялец
Сообщения: 234
Зарегистрирован: 11.03.2009 12:32:54
Контактная информация:

Сообщение DYUMON »

порываюсь спросить. текстовый файл представляет из себя строки текста? или туда просто без разделения сыпались буквы?
stanilar
постоялец
Сообщения: 289
Зарегистрирован: 09.03.2010 18:09:02

Сообщение stanilar »

alexs писал(а):задача обработки текстового файла - часть какого-то постоянного процесса. И это уже явное нарушение логики разработки.Текстовый файл - это максимиум - обмен данными между приложениями.
....
Если у вас задача обработки данных - используйте нормальную СУБД


Зачем открывать файл, если не нужна обработка данных в файле? DB компоненты сильно упростят и дальнейшую работу, и сопровождение. А уж внешний вид какой будет... Если взять RxDBGrid...

Причем люди давно уже скрестили ужа с ежом, нужно просто протянуть руку и взять что положено.

З.Ы. А вот, кстати, чем Вас файловая система не устраивает вместо СУБД? Для не сложной структуры данных в самый раз (не говорю про EAV и т.п., просто не сложная структура данных).

З.З.Ы Да и нет тут явной нарушении логики разработки, для несложной структуры данных СУБД - просто дополнительные тормоза.
Ответить