To search for a specific substring within any type of file, we can use this rather complex function.
function ScanFile(const filename: string; const forString: string;
caseSensitive: Boolean ): LongInt; const BufferSize= $8001; var pBuf, pEnd, pScan, pPos: Pchar; filesize: LongInt; bytesRemaining: LongInt; bytesToRead: Integer; F: File; SearchFor: Pchar; oldMode: Word; begin result := -1; if (Length(forString) = 0) or (Length(filename) = 0) then Exit; SearchFor := nil; pBuf := nil; AssignFile(F, filename); oldMode := FileMode; FileMode := 0; Reset(F, 1); FileMode := oldMode; try SearchFor := StrAlloc(Length(forString) + 1); StrPCopy(SearchFor, forString); if not caseSensitive then AnsiUpper(SearchFor); GetMem(pBuf, BufferSize); filesize := System.Filesize(F); bytesRemaining := filesize; pPos := nil; while bytesRemaining > 0 do begin if bytesRemaining >= BufferSize then bytesToRead := Pred(BufferSize) else bytesToRead := bytesRemaining; BlockRead(F, pBuf^, bytesToRead, bytesToRead); pEnd := @pBuf[bytesToRead]; pEnd^:= #0; pScan := pBuf; while pScan < pEnd do begin if not caseSensitive then AnsiUpper(pScan); pPos := StrPos(pScan, SearchFor); if pPos <> nil then begin 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 seek(F, FilePos(F) - Length(forString)); bytesRemaining := bytesRemaining + Length(forString); end; end; finally CloseFile(F); if SearchFor <> nil then StrDispose(SearchFor); if pBuf <> nil then FreeMem(pBuf, BufferSize); end; end; ... procedure TForm1.Button1Click(Sender: TObject); var position: integer; begin position := ScanFile('c:\filename.txt', 'searchphrase', true); if position <> -1 then
ShowMessage('Text found at position: ' + IntToStr(position))
else
ShowMessage('Not found');
end;
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου