首页  编辑  

从文件中查找字符串

Tags: /超级猛料/Stream.File.流、文件和目录/文件操作/   Date Created:

下面的函数好像有BUG:

function ScanFile ( const FileName : string ; const Sub : 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 ( Sub ) = 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 ( Sub ) + 1 );

   StrPCopy ( SearchFor , Sub );

    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 < 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

       Seek ( F , FilePos ( F ) - Length ( Sub ));

       bytesRemaining := bytesRemaining + Length ( Sub );

      end ;

    end ; { While }

  finally

   CloseFile ( F );

    if SearchFor <> nil then StrDispose ( SearchFor );

    if pBuf <> nil then FreeMem ( pBuf , BufferSize );

  end ;

end ; { ScanFile }