Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 3 425

/ вопрос открыт /

Здравствуйте, уважаемые эксперты!

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

Моя задача - организовать поиск и выводить в окошке конкретные сеансы.
Поскольку файл большой желательно организовать возможность поиска с
конца файла, но я не нашел в Дельфи средств как это сделать.

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

К вопросу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки вопроса)

Avtandil Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Avtandil (статус: Посетитель)
Вопрос отправлен: 20 ноября 2009, 17:38
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, Avtandil!
я бы эту задачку решал так.
Вначале весь файл пробегается быстро и формируется индекс, куда записывается
- дата
- строка в файле
потом, когда надо найти по конкретной дате - смотрим в индекс, сразу знаем, где искать.
если надо найти какой файл был за какую дату скачан - просматриваем файл, ищем нужные подстроки, а потом по индексу восстанавливаем дату - надо найти такую запись, номер строки которой меньше заданной.

если это лог, который постоянно обновляется, то индекс можно просто "достраивать". смотрим в нашем индексе последюю строку, и начинаем парсить файл с этой строки и до конца.
Сам парсинг примитивный. ну где то так

line := 0;
assignfile(f, 'log.dat');
reset(f);
while not eof(f) do begin
  readln(f, s);
  inc(line);
  if s = '********....***' then begin
    readln(f, s); //тут у нас дата
    inc(line);
    //как то разбираем дату, добавляем в массив и\или индексный файл
  end;
end;
CloseFile(f);
идея понятна?

При использовании индекса поиск будет очень быстрый.
Если непонятны детали - пишите что именно.

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 20 ноября 2009, 18:08
Оценка за ответ: 4


Мини-форум вопроса

Всего сообщений: 14; последнее сообщение — 23 ноября 2009, 14:25; участников в обсуждении: 3.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 20 ноября 2009, 18:59 [#1]:

на одну дату один сеанс? или, все-таки, в первой строке дата-время сеанса? Насколько большой файл?

20 ноября 2009, 21:57: Вопрос перемещён из тематического раздела Delphi » Общие вопросы по программированию в раздел Delphi » Алгоритмы, преобразования модератором Ерёмин А.А.

Avtandil

Avtandil (статус: Посетитель), 20 ноября 2009, 23:36 [#2]:

>Мережников Андрей (статус: 8-ой класс), 20 ноября 2009, :18:59:

>на одну дату один сеанс? или, все-таки, в первой строке >дата-время сеанса? Насколько большой файл?

Выводить на экран посеансно, а сеанс каждый час, то есть на дату может быть около 30 сеансов, при поиске находим первый, а дальше просто прокрутка вперед.
Файл около 40 метров, но может быть до ста.
Avtandil

Avtandil (статус: Посетитель), 20 ноября 2009, 23:43 [#3]:

Вадим ! Спасибо за ответ. Вопрос в том как создать этот массив. Не хотелось бы организовывать новый файл. Можно ли это все делать в памяти при запуске программы ? И как вывести на экран результаты конкретного сеанса, если он удовлетворяет условию поиска по дате либо по имени файла ?
Вадим К

Вадим К (статус: Академик), 21 ноября 2009, 02:26 [#4]:

всё зависит от размера файла. Может индекс можно и в памяти держать.

второй вопрос)
находим номер строки, где есть нужный файл. Потом по индексу проходим от начала до тех пор, пока номер строки с файлом не станет меньше номера строки в индексе. После этого возвращаемся по индексу один раз назад.
теперь можно вырезать кусок лога, где нужный сеанс.
Галочка "подтверждения прочтения" - вселенское зло.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 21 ноября 2009, 07:15 [#5]:

в качестве индекса можно попробовать использовать TStringList, если в него записывать только информацию, которую предлагает Вадим К. Так проще, на мой взгляд, будет организовать поиск. Например записывать дату и номер строки как пару "Имя-значение" (Name - Values).
Avtandil

Avtandil (статус: Посетитель), 21 ноября 2009, 08:57 [#6]:

Вадим, Андрей, спасибо за советы. Буду пробовать TStringList.

А как потом можно организовать переход к нужной строке, только n раз Readln? Вот есть компонент FindDlg, так там реализован поиск в обратном направлении, как это можно реализовать в случае с индексами ?
Вадим К

Вадим К (статус: Академик), 21 ноября 2009, 14:48 [#7]:

1) в данном случае я даже не знаю, как красиво использовать TStringList (не, код я с ним напишу, но мне будет стыдно за него). Я бы лично сделал так (это только заготовок классов!!!)
type
  TRec = class
  public
    property number:integer;
    property DateTime:TDateTime;
    procedure Show;
  end;
  TIndex = class
  private
    List:TList;
  public
    procedure Add(nunmber:integer; db:TDateTime);
    function FindByLine(number:Integer):integer;
    procedure LoadFromFile(filename:string);
    property Count:integer;
    property Items[index:integer]:TRec; default;
  end;
и теперь например реальный код
  var ind:TIndex;
begin
  ind := TIndex.Create;
  ind.LoadFromFile('test.dat');
  for i:= 0 to ind.Coount - 1 do 
   ind[i].Show;
  ind.free;
Интересно?

2) переход к нужной строке. то есть вычитать нужную строку? да, можно просто отсчитать нужное кол-во readln в пустом цикле. Но у нас же индекс! кто нам мешает хранить позицию символьную, тогда с помощью FilePos можно узнать текущую позицию в файле при составлении индекса, а когда надо перейти туда, то всего одной функцией Seek. правда последняя функция не работает с текстовыми файлами, но разве нас это остановит??? Никто не мешает открыть его как типизированный...

3)

Цитата (Avtandil):

FindDlg, так там реализован поиск в обратном направлении

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

Avtandil (статус: Посетитель), 22 ноября 2009, 13:38 [#8]:

Вадим !

К сожалению я не очень силен в Дельфи, так что мне надо немного подробнее разжевать ;-)
Вот сейчас изучаю вашу статью о виртуальном ListView, это можно приспособить для первичного прогона файла и индексирования ? И если можно немного подробнее о индексах. Спасибо !

а файл у меня порядка 35 метров.
Вадим К

Вадим К (статус: Академик), 22 ноября 2009, 22:23 [#9]:

в статье есть интересные вещи. но не надо никогда смешивать визуальные компоненты и обработку. Это ужасно.
А что о индексах хочется узнать?
Галочка "подтверждения прочтения" - вселенское зло.
Avtandil

Avtandil (статус: Посетитель), 23 ноября 2009, 10:11 [#10]:

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

Вадим К (статус: Академик), 23 ноября 2009, 11:15 [#11]:

Мне что, полностью писать код?
Галочка "подтверждения прочтения" - вселенское зло.
Avtandil

Avtandil (статус: Посетитель), 23 ноября 2009, 12:55 [#12]:

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

Вадим К (статус: Академик), 23 ноября 2009, 13:41 [#13]:

не надо смешивать компоненты и индексы. Одно другому не мешает. оно просто параллельно.
Галочка "подтверждения прочтения" - вселенское зло.
Avtandil

Avtandil (статус: Посетитель), 23 ноября 2009, 14:25 [#14]:

Вот блин тут то мне знаний и не хватает...

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

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:45
Выполнено за 0.03 сек.