function ScanFile(
const filename:
String;
forString: WideString;
caseSensitive: Boolean ): LongInt;
{ returns position of string in file or -1, if not found }
const
BufferSize= $8000;
{ 32K bytes }
var
Buf: WideString;
filesize, bytesRemaining, bytesToRead, bytesReaded, i: Integer;
F:
File of Widechar;
oldMode: Word;
begin
Result := -1;
{ assume failure }
if (Length( forString ) = 0)
or (Length( filename ) = 0)
then
Exit;
{ open file as binary, 1 byte recordsize }
AssignFile( F, filename );
oldMode := FileMode;
FileMode := 0;
{ read-only access }
Reset(F);
//, 1 );
FileMode := oldMode;
try
if not caseSensitive
then { convert to upper case }
forString := WideUpperCase( forString );
filesize := System.Filesize( F )
and not 1;
bytesRemaining := filesize;
Buf := '
';
while bytesRemaining > 0
do
begin
{ calc how many bytes to read this round }
if bytesRemaining > BufferSize
then
bytesToRead := BufferSize
else
bytesToRead := bytesRemaining;
{ delete the buffer, up to a part for the buffer overall search }
Delete(Buf, 1, Length(Buf) - Length(forString) + 1);
i := Length(Buf);
{ read a buffer }
SetLength(Buf, i + bytesToRead);
BlockRead(F, Buf[i + 1], bytesToRead, bytesReaded);
if bytesToRead <> bytesReaded
then
Exit;
{ read error }
if not caseSensitive
then { convert to upper case }
Buf := WideUpperCase( Buf );
{ scan the buffer }
i := Pos(forString, Buf);
if i > 0
then
begin
Result := FileSize - bytesRemaining - Length(Buf) + i;
Exit;
end;
Dec(bytesRemaining, bytesToRead);
end;
{ While }
finally
CloseFile( F );
end;
end;
{ ScanFile }