Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Быстрый поиск в большом текстовом файле


Hadroran ©   (2010-10-14 10:58:00) 

Привет всем.
Помогите с кодом поиска текста в большом текстовом файле загруженном в StringList.
Вот нашел код

function BMFind(szSubStr, buf: PChar; iBufSize: integer;
 wholeword_only: boolean): integer;
 { Returns -1 if substring not found,
 or zero-based index into buffer if substring found }
var
 iSubStrLen: integer;
 skip: array [char] of integer;
 found: boolean;
 iMaxSubStrIdx: integer;
 iSubStrIdx: integer;
 iBufIdx: integer;
 iScanSubStr: integer;
 mismatch: boolean;
 iBufScanStart: integer;
 ch: char;
begin
 found := False;
 Result := -1;
 iSubStrLen := StrLen(szSubStr);
 if iSubStrLen = 0 then
 begin
   Result := 0;
   Exit
 end;

 iMaxSubStrIdx := iSubStrLen - 1;
 { Initialise the skip table }
 for ch := Low(skip) to High(skip) do skip[ch] := iSubStrLen;
   for iSubStrIdx := 0 to (iMaxSubStrIdx - 1) do
     skip[szSubStr[iSubStrIdx]] := iMaxSubStrIdx - iSubStrIdx;

 { Scan the buffer, starting comparisons at the end of the substring }
 iBufScanStart := iMaxSubStrIdx;
 while (not found) and (iBufScanStart < iBufSize) do
 begin
   iBufIdx := iBufScanStart;
   iScanSubStr := iMaxSubStrIdx;
   repeat
     mismatch := (szSubStr[iScanSubStr] <> buf[iBufIdx]);
     if not mismatch then
       if iScanSubStr > 0 then
       begin // more characters to scan
         Dec(iBufIdx); Dec(iScanSubStr)
       end
       else
         found := True;
   until mismatch or found;
   if found and wholeword_only then
   begin
     if (iBufIdx > 0) then
       found := not IsCharAlpha(buf[iBufIdx - 1]);
     if found then
       if iBufScanStart < (iBufSize - 1) then
         found := not IsCharAlpha(buf[iBufScanStart + 1]);
   end;
   if found then
     Result := iBufIdx
   else
     iBufScanStart := iBufScanStart + skip[buf[iBufScanStart]];
 end;
end;

function StringInFile(strFind, strFileName: string): boolean;
const
 BUFSIZE = 8192;
var
 fstm: TFileStream;
 numread: Longint;
 buffer: array [0..BUFSIZE-1] of char;
 szFind: array [0..255] of char;
 found: boolean;

begin
 StrPCopy(szFind, strFind);
 found := False;
 fstm := TFileStream.Create(strFileName, fmOpenRead);
 repeat
   numread := fstm.Read(Buffer, BUFSIZE);
   if BMFind(szFind, Buffer, numread, false) >= 0 then
       found := True

   else if numread = BUFSIZE then // more to scan
     fstm.Position := fstm.Position - (Length(strFind)-1);

     inc(readed,numread);
     if readed mod 4096 = 0 then
       begin
         form1.label1.caption:= inttostr(readed div 1024 div 1024)+ ' mb read' ;
         Application.ProcessMessages
       end;
 until found or (numread < BUFSIZE);
 fstm.Free;
 Result := found;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 if StringInFile('Find Text','путь\имя_файла.txt') then ShowMessage(format('found at %u',[readed]));
end;

Данный алгоритм работает и быстро, но мне необходимо узнать номер строки и столбца для дальнейшей обработки строки.


KilkennyCat   (2010-10-14 21:41:00) [1]


> в стринг лист быстрее грузится чем в мемо

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

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


Anatoly Podgoretsky   (2010-10-14 14:27:00) [2]

А у "Этого" не получится?


Игорь Шевченко   (2010-10-14 14:23:00) [3]


> в стринг лист быстрее грузится чем в мемо. других вариантов
> решения пока не знаю ((


нанять программиста


Anatoly Podgoretsky   (2010-10-14 13:19:00) [4]


> я знаю что не пахнет. решать то задачу надо. вот и извращаюсь.

Знаешь, но это тебя никак не сдерживает.


Hadroran   (2010-10-14 12:52:00) [5]

сичас папробую )))


Сергей М.   (2010-10-14 12:30:00) [6]

К TRegExpr штатно прилагается достаточно вменяемая русскоязычная справка


Hadroran   (2010-10-14 12:29:00) [7]

а как там организовать поиск


Сергей М.   (2010-10-14 12:28:00) [8]


> удовлетворил любопытство?


Угу.
Но сомнения в необходимости использования для этой цели стринлиста только усилились)
Прайс-лист этот наверняка ведь имеет регулярную структуру записей ?
Так что же мешает воспользоваться механизмом регул.выражений ?
Например, с использованием готовой ее реализации в виде довольно известного класса TRegExpr ?


Hadroran   (2010-10-14 12:23:00) [9]

txt файл в 55 метров прайс лист. Необходимо найти в нем выбранный товар и заменить цену. удовлетворил любопытство?
в стринг лист быстрее грузится чем в мемо. других вариантов решения пока не знаю ((


Сергей М.   (2010-10-14 12:17:00) [10]

А зачем вообще файл бешеного размера грузить в стринг лист ?
Разумное объяснение этой необходимости есть ?


Hadroran   (2010-10-14 11:59:00) [11]

я знаю что не пахнет. решать то задачу надо. вот и извращаюсь.


Сергей М.   (2010-10-14 11:40:00) [12]


> Вот нашел код


Не то ты нашел.
Никаким стринглистом в нем даже не пахнет.


Наверх

Титульная страница Поиск, карта сайта Написать письмо