Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.08.2008, 11:05   #1
Алексей_M
 
Регистрация: 07.08.2008
Сообщений: 5
Вопрос Загрузка и поиск в большом файле.

Доброго времени всем!
Есть очень большой логфайл (текстовый) ~3 Гб (может быть меньше или больше) в котором надо найти строки с теми данными которые необходимы. Программу сделал и даже ищет :-), НО только в файлах которые измеряются в Кб т.е. в маленьких файликах. Это уже хорошо, но нужно в огромных файлах. Программа даже не грузит такой файл и это понятно, думаю что надо использовать поток (), но опыт в их использовании нуль, читал (примеров правда оч. мало) но как прикрутить не совсем понимаю. Прошу помоши.
Ниже программа (если возникнут вопросы), немного обрезанная (Close, Save и т.д.), для уменьшения объёма:
Спасибо.
*********************************** *********************
Код:
procedure TFind_data_logs.open_fileClick(Sender: TObject);

var
  fName: String[80];

begin                     //Загрузка файла
  fname:=enter_file.text;
  with TStringList.create do
  try
    LoadFromFile(fname);
    s:= text;
  finally
    Free;
  end;
end;
//Поиск данных
procedure TFind_data_logs.Find_dataClick(Sender: TObject);
  function StrToArrays(str, r: string; out Temp: TStrings): Boolean;
  var
    j: integer;
  begin
    IF temp <> Nil then
    Begin
      temp.Clear;
      while str <> ''
        do
           Begin
        j := Pos(r,str);
        if j=0 then j := Length(str) + 1;
        temp.Add(Copy(Str,1,j-1));
        Delete(Str,1,j+length(r)-1);
           end;//while
      Result:=True;
    End
    else Result:=False;
  end;//StrToArrays
var
  SL : TStrings;
  i : integer;
begin

  SL := TStringList.Create;
  StrToArrays(s, 'ISO', SL);

  for i := 0 to SL.Count-1 do
  if Pos(What_find.Text, SL[i]) <> 0 then
  Data_list.Lines.Add(SL[i]);
  //Data_list.ScrollBars:=ssVertical;
  
end;

Последний раз редактировалось Stilet; 07.08.2008 в 12:37.
Алексей_M вне форума Ответить с цитированием
Старый 07.08.2008, 13:38   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Алексей_M, один вопрос Вам - текст для поиска (в Вашем примере "ISO") может быть на двух разных строчках? (т.е. часть, например I в конце одной строки, а SO в начале другой?? Если это не так, то поиск делайте так:
Код:
var MyFileTS : TStringList;
...
MyFileTS := TStringList.create;
MyFileTS.LoadFromFile( ИмяФайла);
for i:=0 to MyFileTS.Count - 1 do
  if Pos(FindStr, MyFileTS.Strings[i])>0 then begin
        // нашли в i-й строке искомый текст - строка =  MyFileTS.Strings[i]
        ... делаем что нужно... ну, temp.add(MyFileTS.Strings[i]) например.
   end;
FreeAndNil(MyFileTS);
Serge_Bliznykov вне форума Ответить с цитированием
Старый 07.08.2008, 13:53   #3
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

MyFileTS.LoadFromFile
очень очень ОЧЕНЬ плохо для 3Гб-файла!!

Лучше использовать TFileStream и алгоритм Бойера-Мура (он ищет строку по начальному и конечному символу, очень быстро отьрасывая весь мусор. Комптех рулит ). Когда-то контрольную на подобную тему делал, попробую найти
пыщь
JTG вне форума Ответить с цитированием
Старый 07.08.2008, 13:57   #4
Hollander
Участник клуба
 
Аватар для Hollander
 
Регистрация: 03.05.2007
Сообщений: 1,189
По умолчанию

В любом случае нужно как-то уменьшть размер файла, ты об этом не думал. Напиши что в нем такое лежит, если не секрет, т.к. я бы н е хотел чтобы у меня лог был 3 гига. Волзможно есть другой подход.
Hollander вне форума Ответить с цитированием
Старый 07.08.2008, 14:50   #5
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

В 1.4Гб-файле нашёл строку в конце ~за 80 секунд (WinHEX - около минуты), скопипастил с http://articles.org.ru/cn/showdetail.php?cid=6427

Сам поиск лучше запихать в отдельный thread, когда found=true вызывать процедуру, приостанавливающую его и выводящую запрос "искать далее, да/нет", если да - установить found=false и запустить поток дальше, если нет - tfilestream.free и прибить thread. Но это уж вы как нибудь сами

* кстати да, что это за лог такой на 3 гига, если не секрет?
Вложения
Тип файла: rar Supa-pupa-search.rar (4.0 Кб, 111 просмотров)
пыщь

Последний раз редактировалось JTG; 07.08.2008 в 14:53.
JTG вне форума Ответить с цитированием
Старый 07.08.2008, 16:54   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

JTG - Вы всё пишете абсолютно правильно.
за одним малюсеньким уточнением. Пару лет назад я озаботился, как поэффективнее работать с текстовыми файлами. Так вот, тот вариант, что Вы предложили - самый быстрый. но! Внимание! я Вас очень прошу - попробуйте код, который я привёл в своем посте #2.
и на Вашем файле (который 1.4 ГБ) найти ту же информацию, что Вы искали... И замерить время...
я думаю, что оно будет больше, может даже в разы..
но не настолько плохо, как Readln(...) $)))
Жду результатов.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 07.08.2008, 19:12   #7
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

На том же файле не могу, он бинарный, в смысле фильм
Вот сейчас сохранится аналогичный текстовый, его и попробую загрузить
--
Ну, скажем так, я не удивлён
First chance exception at $7C812A23. Exception class EOutOfMemory with message 'Out of memory'. Process Project1.exe (1216) на MyFileTS.LoadFromFile
Не влезет туда такой объем информации, он же наверняка весь сразу грузится
пыщь

Последний раз редактировалось JTG; 07.08.2008 в 19:32.
JTG вне форума Ответить с цитированием
Старый 07.08.2008, 20:55   #8
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 15,551
По умолчанию

Я не уверен, но вроде в TStringList есть ограничение на количество строк: 65535. Опять же, возможно это у меня из старой памяти, когда писали под Win 3.11 на Делфи 1, но там это точно было.
Arigato вне форума Ответить с цитированием
Старый 08.08.2008, 00:30   #9
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Уважаемый JTG. Приношу персонально Вам (а также, разумеется, автору вопроса и всем участникам дискуссии) свои глубочайшие извинения. я был неправ. Тут же речь идёт не о больших текстовых файлах, тут речь о ГИГАНТСКИХ текстовых файлах! А мне почему-то втемяшилось в голову, что речь идёт о мегабайтных файлах..
Нет, для гиговых файлов TStringList категорически не подходит (его поле деятельности файлы на десятки МБ, максимум - несколько сотен МБ, но не больше!!!)
Вот, попробовал, создал текстовый файл на 1 ГБ (20000 строк) - LoadFromFile грузила его около пяти минут ;-(( Да и вообще, большие файлы нельзя целиком грузить в память - это смерти подобно...


Цитата:
Сообщение от Arigato
Я не уверен, но вроде в TStringList есть ограничение на количество строк: 65535.
Нет, вот чего нет, так того нет.. :-) это не так... вот, проверил, на десять миллионов строк заполняется буквально за несколько секунд (у меня за пять секунд) (кстати, он получился менее 160 МБ :
Код:
  for i:=1 to 10000000 do
     TS.Add('stroka: '+IntToStr(i));
Serge_Bliznykov вне форума Ответить с цитированием
Старый 08.08.2008, 16:40   #10
Алексей_M
 
Регистрация: 07.08.2008
Сообщений: 5
Сообщение

Доброго времени!
Serge_Bliznykov: ISO-Начало строки, конец строки это любой символ.
Все идёт по строчно и не режется.
Пр.
ISO123jtgh56fh<7880>u90............ ...
ISO9765ggsjgdjjtr-=>>899............... и т.д.
Смысл такой, в строке найдены искомые данные, берётся часть строки в лево до ISO (начало строки) и вправо до след. ISO на след строке (этим опред. конец набора данных и получается целая строка с искомыми данными

Hollander & JTG: Это тех. лог. работы терминала, данных много. Порезать пока нельзя (думал об этом), узнал что в перспективе есть (сервером занимаются другие). В архивации логики никакой, может месяц заполнятся, а может и полгода. Смысл, чел, возмоно пьяный (неадекватный) деньги заплатил и тока через месяц вспомнил что где-то что-то как-то не прошло и где-то его послали, вот тут ищется раб. терм. в логе, а он то уже ого-го. Так же см. первую часть.

Спасибо за ссылку, буду пробовать. Как сделаю дам ответ, но не знаю когда, т.к. в пока опыта в таких вещах маловато.

Спасибо всем.
Алексей_M вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поиск в файле Zandrey Microsoft Office Excel 8 05.09.2008 12:23
поиск в файле Elm0 Паскаль, Turbo Pascal, PascalABC.NET 14 07.06.2008 22:41
Поиск в файле lin Помощь студентам 3 25.05.2007 08:40
Поиск в файле asale Microsoft Office Excel 1 15.05.2007 23:33