Форум: "Основная";
Текущий архив: 2004.11.14;
Скачать: [xml.tar.bz2];
Внизаналог find in files из delphi Найти похожие ветки
← →
ali_t (2004-10-24 16:00) [0]Здравствуйте мне надо написать программу как find in files в delphi. чтобы искала заданную строку в текстовых файлах и выдавала результат в виде списка , по которому можно было бы перейти на найденную позицию в файле.
как это можно сделать ?
← →
Anatoly Podgoretsky © (2004-10-24 16:11) [1]Ближайший аналог POS
← →
ali_t (2004-10-27 01:52) [2]разговор сам с собой //ответ из другого форума
Во-первых, для поиска текста в указанном файле и получения позиции строки в указанном файле, воспользуйся этой процедурой. Возвращает позицию указанной строки, или -1, если она не найдена.
Код
function ScanFile(const FileName: string;
const forString: string;
caseSensitive: Boolean): Longint;
{ returns position of string in file or -1, if not found }
const
BufferSize = $8001; { 32K+1 bytes }
var
pBuf, pEnd, pScan, pPos: PChar;
filesize: LongInt;
bytesRemaining: LongInt;
bytesToRead: Word;
F: file;
SearchFor: PChar;
oldMode: Word;
begin
Result := -1; { assume failure }
if (Length(forString) = 0) or (Length(FileName) = 0) then Exit;
SearchFor := nil;
pBuf := nil;
{ open file as binary, 1 byte recordsize }
AssignFile(F, FileName);
oldMode := FileMode;
FileMode := 0; { read-only access }
Reset(F, 1);
FileMode := oldMode;
try { allocate memory for buffer and pchar search string }
SearchFor := StrAlloc(Length(forString) + 1);
StrPCopy(SearchFor, forString);
if not caseSensitive then { convert to upper case }
AnsiUpper(SearchFor);
GetMem(pBuf, BufferSize);
filesize := System.Filesize(F);
bytesRemaining := filesize;
pPos := nil;
while bytesRemaining > 0 do
begin
{ calc how many bytes to read this round }
if bytesRemaining >= BufferSize then
bytesToRead := Pred(BufferSize)
else
bytesToRead := bytesRemaining;
{ read a buffer full and zero-terminate the buffer }
BlockRead(F, pBuf^, bytesToRead, bytesToRead);
pEnd := @pBuf[bytesToRead];
pEnd^ := #0;
{ scan the buffer. Problem: buffer may contain #0 chars! So we
treat it as a concatenation of zero-terminated strings. }
pScan := pBuf;
while pScan < pEnd do
begin
if not caseSensitive then { convert to upper case }
AnsiUpper(pScan);
pPos := StrPos(pScan, SearchFor); { search for substring }
if pPos <> nil then
begin { Found it! }
Result := FileSize - bytesRemaining +
Longint(pPos) - Longint(pBuf);
Break;
end;
pScan := StrEnd(pScan);
Inc(pScan);
end;
if pPos <> nil then Break;
bytesRemaining := bytesRemaining - bytesToRead;
if bytesRemaining > 0 then
begin
{ no luck in this buffers load. We need to handle the case of
the search string spanning two chunks of file now. We simply
go back a bit in the file and read from there, thus inspecting
some characters twice
}
Seek(F, FilePos(F) - Length(forString));
bytesRemaining := bytesRemaining + Length(forString);
end;
end; { While }
finally
CloseFile(F);
if SearchFor <> nil then StrDispose(SearchFor);
if pBuf <> nil then FreeMem(pBuf, BufferSize);
end;
end; { ScanFile }
Теперь небольшая адаптация под твои запросы:
1) Если файлы, в которых тебе надо искать строку, известны и лежат в каком-либо списке или массиве, то небольшой пример таков. Пусть, есть следующие переменные:
FileList : TStringList; //Список путей к файлам для поиска строки
SearchStr : String; //Строка для поиска
И объекты на форме:
ListView1 - Список результатов. Формат отображения стоит vsReport. Две колонки - Имя файла и Позиция.
Memo1 - В него будет загружаться файл и осуществляться переход на нужную позицию
Поиск файлов
Код
const
SearchStr="Строка для поиска";
var
I:Integer;
FileList : TStringList;
CurPos : Integer;
N:TListItem;
begin
ListView1.Items.Clear;
For I := 0 to FileList.Count-1 do
begin
CurPos:=ScanFile(FileList[I], SearchStr, False);
If CurPos=-1 then Continue;
N:=ListView1.Items.Add;
N.Caption:=ExtractFileName(FileList[I]);
N.SubItems.Add(IntToStr(CurPos));
end;
end;
Отображение. Процедура OnDoubleClick компоненты ListView1
Код
var
CurFile:String;
CurPos:Integer;
begin
If ListView1.ItemIndex<0 then Exit;
CurFile:=ListView1.Items[ListView1.ItemIndex].Caption;
CurPos:=StrToInt(ListView1.Items[ListView1.ItemIndex].SubItems[0]);
Memo1.Lines.LoadFromFile(CurFile);
Memo1.SelStart:=CurPos;
Memo1.SetFocus;
end;
Вроде все...
--------------------
- Папа, что такое флуд?
- Гы, сынок, ЛОЛ.
Спасибо за ответы.
у меня ещё вопросы , моя программа должна искать строку в файлах html
и выдавать результат в TWebBrowser вместо TMemo ,но в html теги тоже будут
попадать в обработку и в результате отображения курсор встанет не на нужное место-как можно исключить из обработки теги? и эта процедура после первого
нахождения строки остальную часть файла пропускает? и как можно прокрутить TWebBrowser вслед за установленным курсором? и как сделать чтоб
курсор переходил не к позиции в строке ,а к началу самой строки.
пока.
← →
ali_t (2004-10-28 01:06) [3]News ?
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.11.14;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.039 c