Mega Code Archive

 
Categories / Delphi / Files
 

How to search a file for a string

Title: How to search a file for a string function ScanFile(const FileName: string; const forString: string; caseSensitive: Boolean): Longint; const BufferSize = $8001; { 32K+1 bytes } var pBuf, pEnd, pScan, pPos: PChar; filesize: LongInt; bytesRemaining: LongInt; bytesToRead: Integer; F: file; SearchFor: PChar; oldMode: Word; begin { assume failure } Result := -1; 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; pScan := pBuf; while pScan 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 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 } // Search in autoexec.bat for "keyb" with case insensitive procedure TForm1.Button1Click(Sender: TObject); var Position: integer; begin Position := ScanFile('c:\autoexec.bat', 'keyb', False); ShowMessage(IntToStr(Position)); end;