| 
| 
 | Вопрос # 3 425/ вопрос открыт / | 
 |  Здравствуйте, уважаемые эксперты!
 Имеется  текстовый  файл  описывающий  сеансы связи, сеансы отделяются
 друг от друга строкой, состоящей из звездочек.
 
 Моя задача - организовать поиск и выводить в окошке конкретные сеансы.
 Поскольку  файл  большой  желательно организовать возможность поиска с
 конца файла, но я не нашел в Дельфи средств как это сделать.
 
 Также   надо   реализовать   поиск  по  дате  сеанса (то есть вытащить
 информацию о дате из первой строки сеанса) и по одной из строк, но
 чтобы  результат  поиска  выводился  посеансно,  то  есть  между двумя
 строками, состоящими из одних звездочек.
 К  сожалению  все  сеансы описываются разным количеством строк и могут
 быть отделены друг от друга только строкой звездочек.
 Кусочек файла для примера ниже прилагается.
 К вопросу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки вопроса) 
|  |   Вопрос задал: 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 (статус: Посетитель), 20 ноября 2009, 23:36 [#2]:>Мережников Андрей (статус: 8-ой класс), 20 ноября 2009, :18:59: 
 >на одну дату один сеанс? или, все-таки, в первой строке >дата-время сеанса? Насколько большой файл?
 
 Выводить на экран посеансно, а сеанс каждый час, то есть на дату может быть около 30 сеансов, при поиске находим первый, а дальше просто прокрутка вперед.
 Файл около 40 метров, но может быть до ста.
 |  
|   | Avtandil (статус: Посетитель), 20 ноября 2009, 23:43 [#3]:Вадим ! Спасибо за ответ. Вопрос в том как создать этот массив. Не хотелось бы организовывать новый файл. Можно ли это все делать в памяти при запуске программы ? И как вывести на экран результаты конкретного сеанса, если он удовлетворяет условию поиска по дате либо по имени файла ? |  
|   | Вадим К (статус: Академик), 21 ноября 2009, 02:26 [#4]:всё зависит от размера файла. Может индекс можно и в памяти держать. 
 второй вопрос)
 находим номер строки, где есть нужный файл. Потом по индексу проходим от начала до тех пор, пока номер строки с файлом не станет меньше номера строки в индексе. После этого возвращаемся по индексу один раз назад.
 теперь можно вырезать кусок лога, где нужный сеанс.
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Мережников Андрей (статус: Абитуриент), 21 ноября 2009, 07:15 [#5]:в качестве индекса можно попробовать использовать TStringList, если в него записывать только информацию, которую предлагает Вадим К. Так проще, на мой взгляд, будет организовать поиск. Например записывать дату и номер строки как пару "Имя-значение" (Name - Values). |  
|   | 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 (статус: Посетитель), 22 ноября 2009, 13:38 [#8]:Вадим ! 
 К сожалению я не очень силен в Дельфи, так что мне надо немного подробнее разжевать
  Вот сейчас изучаю вашу статью о виртуальном ListView, это можно приспособить для первичного прогона файла и индексирования ? И если можно немного подробнее о индексах. Спасибо !
 
 а файл у меня порядка 35 метров.
 |  
|   | Вадим К (статус: Академик), 22 ноября 2009, 22:23 [#9]:в статье есть интересные вещи. но не надо никогда смешивать визуальные компоненты и обработку. Это ужасно. А что о индексах хочется узнать?
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Avtandil (статус: Посетитель), 23 ноября 2009, 10:11 [#10]:ну вот хотя бы применимо к моей задаче - как их загнать в память (при соблюдении условия - что в строке звездочки), как к определенному индексу потом получить доступ. и как все это оптимизировать. |  
|   | Вадим К (статус: Академик), 23 ноября 2009, 11:15 [#11]:Мне что, полностью писать код? Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Avtandil (статус: Посетитель), 23 ноября 2009, 12:55 [#12]:Хорошо бы было в виде статьи они у вас достаточно подробные и там можно рассмотреть все основные случаи с примерами. Как вот например есть статья о работе с файлами, так же с про индексы сделать - как с ними работать в различных компонентах. |  
|   | Вадим К (статус: Академик), 23 ноября 2009, 13:41 [#13]:не надо смешивать компоненты и индексы. Одно другому не мешает. оно просто параллельно. Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Avtandil (статус: Посетитель), 23 ноября 2009, 14:25 [#14]:Вот блин тут то мне знаний и не хватает... |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |