Открыть текстовый файл размером в 3 Гб
Модератор: Модераторы
Открыть текстовый файл размером в 3 Гб
Здравствуйте!
Появилась такая задача, нужно открыть текстовый файл в несколько гектар, полазить по нему и кое что там изменить, перегнать из кодировки windows в UTF.
Мелкие в сотни метров спокойно грузятся в TStringList.
Но сейчас прога подвисает и срабатывает исключение.
Подскажите, как такое вобще провернуть?
з.ы. Может ли размер оперативки исправить ситуацию? (Сейчас 4 гектара оперативки и столько же подкачки. Ставил подкачку в 16 гектар, ничего не изменилось.)
з.з.ы. EmEditor спокойно файл открывает
Появилась такая задача, нужно открыть текстовый файл в несколько гектар, полазить по нему и кое что там изменить, перегнать из кодировки windows в UTF.
Мелкие в сотни метров спокойно грузятся в TStringList.
Но сейчас прога подвисает и срабатывает исключение.
Подскажите, как такое вобще провернуть?
з.ы. Может ли размер оперативки исправить ситуацию? (Сейчас 4 гектара оперативки и столько же подкачки. Ставил подкачку в 16 гектар, ничего не изменилось.)
з.з.ы. EmEditor спокойно файл открывает
Программа и ОС 32х разрядная или 64х? 32х разрядная программа не потянет за раз такое.
Насколько я помню тип данных String ограничен размером в 2 с чем то Гб, а TStringList жанглирует этим типом.
Если у тебя только перегнать задача, то может стоит функциями побайтового чтения файла читать скажем по 1Мб..100Мб в буферную строку, конвертировать и записывать в результирующий итоговый файл?
Насколько я помню тип данных String ограничен размером в 2 с чем то Гб, а TStringList жанглирует этим типом.
Если у тебя только перегнать задача, то может стоит функциями побайтового чтения файла читать скажем по 1Мб..100Мб в буферную строку, конвертировать и записывать в результирующий итоговый файл?
Я такие файлы открывал с помощью TextFile и построчным считыванием ReadLn().
- Vapaamies
- постоялец
- Сообщения: 292
- Зарегистрирован: 24.07.2012 22:37:59
- Откуда: Санкт-Петербург
- Контактная информация:
resident писал(а):Мелкие в сотни метров спокойно грузятся в TStringList.
Но сейчас прога подвисает и срабатывает исключение.
Выходом, думаю, будет написанная вручную загрузка из файла в StringList через скользящий буфер. Через ReadLn -- она и есть, только размер буфера уж очень маленький.
Вместо скользящего буфера еще отображение на память можно попробовать, особенно в 64-битной ОС.
Есть TStringStream, очень быстрая вещь, если заранее выделять нужную память через SetSize
http://lazarus-ccr.sourceforge.net/docs ... tream.html
http://www.gunsmoker.ru/2011/11/blog-post_12.html
http://lazarus-ccr.sourceforge.net/docs ... tream.html
http://www.gunsmoker.ru/2011/11/blog-post_12.html
Ужос...
Технологии построчной работы с файлами утрачены напрочь и даже не вспоминаются (намёка Vadim'a никто не понял). Маниакальная привязанность считать все сразу в память упирается в категорическое незнание матчасти, в частности того, что на 32-битной windows под пользовательские данные процесса отводится не более 2 Гб и все остальное - танцы с бубнами.
Коллеги, вы что, реально считаете, что если такой файл прочесть сразу в память и ковыряться уже в ней, то это ускорит работу? Ну-ну.
Технологии построчной работы с файлами утрачены напрочь и даже не вспоминаются (намёка Vadim'a никто не понял). Маниакальная привязанность считать все сразу в память упирается в категорическое незнание матчасти, в частности того, что на 32-битной windows под пользовательские данные процесса отводится не более 2 Гб и все остальное - танцы с бубнами.
Коллеги, вы что, реально считаете, что если такой файл прочесть сразу в память и ковыряться уже в ней, то это ускорит работу? Ну-ну.
Спасиб за ответы. Пока остановился на варианте:
Скорость устраивает (пробегает весь файл без какой-либо обработки за 45 секунд).
Все к этому идет, вы знали
Пересобрал 64-битный ехе, тоже виснет. Все сразу грузить похоже не вариант, потому что непонятно все напрочь зависло или еще есть шанс, что доделает.
Vadim писал(а):TextFile и построчным считыванием ReadLn()
Скорость устраивает (пробегает весь файл без какой-либо обработки за 45 секунд).
Vapaamies писал(а):Выходом, думаю, будет написанная вручную загрузка из файла в StringList через скользящий буфер.
Все к этому идет, вы знали
Sharfik писал(а):Программа и ОС 32х разрядная или 64х? 32х разрядная программа не потянет за раз такое.
Пересобрал 64-битный ехе, тоже виснет. Все сразу грузить похоже не вариант, потому что непонятно все напрочь зависло или еще есть шанс, что доделает.
resident писал(а):Все сразу грузить похоже не вариант
Не вариант.
Кроме элементарной нехватки памяти на строки можно элементарно перегрузить индексатор StringList'a (при таком размере файла количество строк непредстказуемо) или саму систему управления динамическими массивами.
resident писал(а):Подскажите, как такое вобще провернуть?
Под виндой есть такое понятие как Memory Mapped File, под делфей для этой технологии есть куча компонент, лично у меня есть даже раализация буфера TDataSet, он на этой технологии теперь спокойно 20-30 гиг за раз ест.
Думаю, под линух есть аналог, но не знаю как он называется...
З.Ы. Если задача - перегнать, может сразу а БД? Уверен, сторонних компонент под такую задачу будет навалом.
З.З.Ы И, кстати, винда умеет работать с файлами как с БД, погуглите microsoft jet database engine file connection string. У Марко, в его небезизвестной книге, подробно написано как с ним работать.
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
- Откуда: г.Ставрополь
- Контактная информация:
stanilar
Использование DB компонент подразумевает что задача обработки текстового файла - часть какого-то постоянного процесса. И это уже явное нарушение логики разработки.
Текстовый файл - это максимиум - обмен данными между приложениями.
Во всех остальных случаях - используйте форматированные данные.
Если у вас задача обработки данных - используйте нормальную СУБД.
Это стандартная паскальная функция - зачем ей устаревать?
Добавлено спустя 47 секунд:
ЗЫ
Микроскопом можно гвозди забивать - я знаю.
Но как-то это ... неудобно...
Использование DB компонент подразумевает что задача обработки текстового файла - часть какого-то постоянного процесса. И это уже явное нарушение логики разработки.
Текстовый файл - это максимиум - обмен данными между приложениями.
Во всех остальных случаях - используйте форматированные данные.
Если у вас задача обработки данных - используйте нормальную СУБД.
stanilar писал(а):А разве readln не deprecated?
Это стандартная паскальная функция - зачем ей устаревать?
Добавлено спустя 47 секунд:
ЗЫ
Микроскопом можно гвозди забивать - я знаю.
Но как-то это ... неудобно...
Полностью согласен с авторами указывавшими на readln. Прекрасная функция для последовательного чтения файлов. Только не забудьте объявить файл как текстовый:
а дальше стандартные assign и restet с writeln.
Сам такими методами парсил за минуты гигабайтные файлы. Все получалось даже очень шустро
Код: Выделить всё
Var
t : text;а дальше стандартные assign и restet с writeln.
Сам такими методами парсил за минуты гигабайтные файлы. Все получалось даже очень шустро
порываюсь спросить. текстовый файл представляет из себя строки текста? или туда просто без разделения сыпались буквы?
alexs писал(а):задача обработки текстового файла - часть какого-то постоянного процесса. И это уже явное нарушение логики разработки.Текстовый файл - это максимиум - обмен данными между приложениями.
....
Если у вас задача обработки данных - используйте нормальную СУБД
Зачем открывать файл, если не нужна обработка данных в файле? DB компоненты сильно упростят и дальнейшую работу, и сопровождение. А уж внешний вид какой будет... Если взять RxDBGrid...
Причем люди давно уже скрестили ужа с ежом, нужно просто протянуть руку и взять что положено.
З.Ы. А вот, кстати, чем Вас файловая система не устраивает вместо СУБД? Для не сложной структуры данных в самый раз (не говорю про EAV и т.п., просто не сложная структура данных).
З.З.Ы Да и нет тут явной нарушении логики разработки, для несложной структуры данных СУБД - просто дополнительные тормоза.
