Задача: просмотр текстового файла

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

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

Задача: просмотр текстового файла

Сообщение donpadlo » 23.01.2012 23:12:14

Есть задача организовать просмотр некого текстового файла. Компонент memo не подходит, т.к. он предварительно загружает весь файл целиком в память (что не приемлимо для файлов ОЧЕНЬ большого размера).

В принципе нечто написал,выводом текста на канву,одна проблема: если организовать "листание" страниц вперед у меня не вызывает проблем, то с листанием "назад" беда. Не могу придумать умный алгоритм поиска предыдущей строки (нужно понимать что "строка" может быть любой длинны и перенос на экране строчки не означает то-же самое в файле). Все алгоритмы которые я придумываю или слишком сложны или могут теоретически вызывать сбивание абзацев.
Аватара пользователя
donpadlo
новенький
 
Сообщения: 58
Зарегистрирован: 18.08.2011 09:14:53

Re: Задача: просмотр текстового файла

Сообщение alexs » 23.01.2012 23:58:08

А тупой поиск символов CRLF чем не устраивает?
Только сразу оговориться - напрямую в файле - это дохлый номер.
А вот если будешь работать с буфером упреждающего чтения - то результат будет приемлем.
PS
У меня была подобная задача - сеансово искать последовательности определённых симовлов в файлах размерами несколько сот гиг. Причём туда постоянно дописывались данные.
Я сохранял позицию последнего обращения в конфиге между сеансами. А в следующем сеансе читал в буфер с сохраннённой позиции, выделял в нём строки и делал поиск уже в них.
Работает шустро...
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Задача: просмотр текстового файла

Сообщение donpadlo » 24.01.2012 12:04:43

Так устраивает. Но яж говорю, строка в файле не обязательно обозначает строку на экране. Ширина экрана же может быть меньше длинны строки. Соответственно будут "виртуальные переносы" строки... Т.е. например: допустим строка в файле: 123456789. Допустим ширина экрана 4 символа. Допустим позиция текущая курсора - на 9. "Листаем назад", получаем:
Код: Выделить всё
     1
2345
6789

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

Добавлено спустя 3 минуты 14 секунд:
Придется таки все-же видимо "набирать в памяти" сначала строку экрана, а потом уже выводить её на экран. :?
Аватара пользователя
donpadlo
новенький
 
Сообщения: 58
Зарегистрирован: 18.08.2011 09:14:53

Re: Задача: просмотр текстового файла

Сообщение alexs » 24.01.2012 19:29:17

Буфер именно для того и нужен, чтобы ты смог сформировать массив строк, который ты будешь отображать.
А уж потом - над этим массивом, делай что хочешь.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Задача: просмотр текстового файла

Сообщение donpadlo » 25.01.2012 09:12:55

Все хорошо на ПК. Но попробовал с "упреждающей" обработкой файла на WindowsCE - файлик 1 мб, грузился для просмотра 2 минуты :(
Думаю...
Аватара пользователя
donpadlo
новенький
 
Сообщения: 58
Зарегистрирован: 18.08.2011 09:14:53

Re: Задача: просмотр текстового файла

Сообщение Brainenjii » 25.01.2012 10:07:22

Если файлик формируется на большом брате, то можно его сначала нашинковать на желаемые кусочки
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Задача: просмотр текстового файла

Сообщение vada » 25.01.2012 10:29:26

А если по мере просмотра файла "индексировать" его. Т.е. запоминать сдвиг от начала файла до строки, с учетом переносов. Прокрутка назад все равно будет тяжелой (сначала на начало файла потом на нужную стоку), но не надо будет весь файл сначала просматривать. Потом, для уменьшения количества обращений к диску, можно сделать буфер и показывать в том же Memo только окно этого буфера. При приближении к началу или концу буфера считывать некое количество строк.
Аватара пользователя
vada
энтузиаст
 
Сообщения: 691
Зарегистрирован: 14.02.2006 13:43:17

Re: Задача: просмотр текстового файла

Сообщение alexs » 25.01.2012 12:27:56

donpadlo
А почему так долго?
Смысл задачи - только найти начала строк. А потом создать масив строк и скопировать содержимое из буфера по индексам начала в массив.
Тут же нет таких тяжёлых вычислений. И файловые операции сведены к минимуму.
vada
При реально больших файлах сам полный индекс для файла будет очень большим.
Хотя - для файлов порядка 10-100 метров - смысл имеет.
Но у этого варианта недостаток - если надо сразу посмотреть строки конца файла - это будет тормозить. Фактически в этом случаее надо перечитать весь файл.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Задача: просмотр текстового файла

Сообщение donpadlo » 25.01.2012 12:40:41

Вишь в чем дело, нужнож еще высчитывать длинну строки. В каждой строчке может быть разное количество символов из-за разной ширины букв.. Потому и тяжелый процесс на самом деле получается
Аватара пользователя
donpadlo
новенький
 
Сообщения: 58
Зарегистрирован: 18.08.2011 09:14:53

Re: Задача: просмотр текстового файла

Сообщение Brainenjii » 25.01.2012 12:54:57

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

Procedure TForm1.FormPaint(Sender: TObject);
Var
  aRect: TRect;
  aStyle: TTextStyle;
Begin
  aRect.Top := 0;
  aRect.Left := 10;
  aRect.Bottom := 100;
  aRect.Right := 110;
  aStyle.SingleLine := FALSE;
  aStyle.Opaque := FALSE;
  Canvas.TextRect(aRect, 10, 10, 'Привет, прекрасный безумный мир о котором я ' +
    'так мало знаю сейчас', aStyle);
End;

то и расчитывать длину строки, возможно, не нужно
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Задача: просмотр текстового файла

Сообщение donpadlo » 25.01.2012 13:17:09

не не вариант, придется контролировать выход за границы экрана.. Строкаж из файла может быть длиннее заполнения квадрата экрана
Аватара пользователя
donpadlo
новенький
 
Сообщения: 58
Зарегистрирован: 18.08.2011 09:14:53

Re: Задача: просмотр текстового файла

Сообщение alexs » 25.01.2012 14:36:43

donpadlo
1. Отображай моноширинным шрифтом - очень способствует :-)
2. Расчёт свёртки делай 1 раз - после формирования массива строки или после изменения размеров области отображения. Значения кэшируй - например пусть у тебя строится доп массив строк с фактическими значениями для отображения.

Но это уже не будет относится к задаче определения строк в файле.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Задача: просмотр текстового файла

Сообщение vada » 25.01.2012 16:01:15

vada
При реально больших файлах сам полный индекс для файла будет очень большим.
Хотя - для файлов порядка 10-100 метров - смысл имеет.

Мне трудно представить файл порядка 100 метров на WindowsCE. Нет, файл конечно может быть, но додуматься с ним там работать :wink: это как-то стремно...
Но у этого варианта недостаток - если надо сразу посмотреть строки конца файла - это будет тормозить. Фактически в этом случае надо перечитать весь файл.

Это не беда. Ориентировочный размер отображаемого кадра есть. Размер буфера тоже известен. И длинна файла не секрет. В чем проблема заполнить буфер окончанием файла, проиндексировать этот кусок, а потом кадр показать? Организовать этакий виртуальный прямой доступ к файлу.
Согласен, листать в таком случае назад будет напряжно, но это уже вопрос к файловой системе. На WindowsCE это будет, извиняюсь, жопа.
Аватара пользователя
vada
энтузиаст
 
Сообщения: 691
Зарегистрирован: 14.02.2006 13:43:17

Re: Задача: просмотр текстового файла

Сообщение alexs » 25.01.2012 16:22:25

vada писал(а): В чем проблема заполнить буфер окончанием файла, проиндексировать этот кусок, а потом кадр показать? Организовать этакий виртуальный прямой доступ к файлу.

Это мой вариант :D
Т.е на нижнем уровне работаешь с буферами фиксированного размера, а потом превращаешь их строки и индексируешь.
donpadlo
А почему проблема стала именно со строками?
Может изначально условия можно изменить. Ведь есть много хороших вариантов хранения данных :-)
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Задача: просмотр текстового файла

Сообщение Vlad04 » 25.01.2012 18:13:06

donpadlo писал(а):Так устраивает. Но яж говорю, строка в файле не обязательно обозначает строку на экране. Ширина экрана же может быть меньше длинны строки. Соответственно будут "виртуальные переносы" строки... Т.е. например: допустим строка в файле: 123456789. Допустим ширина экрана 4 символа. Допустим позиция текущая курсора - на 9. "Листаем назад", получаем:
Код: Выделить всё
     1
2345
6789

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

Добавлено спустя 3 минуты 14 секунд:
Придется таки все-же видимо "набирать в памяти" сначала строку экрана, а потом уже выводить её на экран. :?

А как по дрругому? Приведенный Вами пример получается при посимвольном чтении файла. При построчном чтении вся строка уже будет в памяти и у Вас уже есть начало строки и, соответственно, начало абзаца. От него и надо плясать.
При испольльзовании посимвольного чтения жесткие тормоза будут именно из-за обращений к файлу.
Если посимвольное чтение является жестким условием, то, кроме текущей позиции в файле, храните текущую позицию на экране, тогда Ваш пример будет работать так:
Код: Выделить всё
Строка в файле:  123456789, ширина экрана 4 символа, позиция в файле - на 9, позиция на экране - 1. "Листаем назад", получаем:
1234
5678
9
Аватара пользователя
Vlad04
новенький
 
Сообщения: 80
Зарегистрирован: 11.12.2007 21:11:19
Откуда: Караганда. Казахстан


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 241

Рейтинг@Mail.ru