Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.11.14;
Скачать: CL | DM;

Вниз

аналог 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;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.027 c
14-1099002605
GanibalLector
2004-10-29 02:30
2004.11.14
Двенадцать заповедей пролетариата


1-1098961192
SNV-Soft
2004-10-28 14:59
2004.11.14
Размытые края TLabel при печати формы...


1-1098960063
_Kirill_
2004-10-28 14:41
2004.11.14
Способы хранения на диске большого кол-ва переменных НЕ в БД


14-1098877983
Charli
2004-10-27 15:53
2004.11.14
RxLib


14-1098683811
syte_ser78
2004-10-25 09:56
2004.11.14
Подарок девушке