![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Быстрый поиск в большом текстовом файле
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]
> Вот нашел код
Не то ты нашел.
Никаким стринглистом в нем даже не пахнет.