File Access Denied Error

I used a routine I found here for doing a quick file search.  I had to alter it a little to accommodate partial strings.  It runs fine until about 100 searches through and then, on the first BlockRead, I receive an exception of "File Access Denied".  The file is opened in FormShow and closed in FormClose and has a filemode of Read Only.  Only this routine accesses it.  I'm sure I'm doing something really dumb but I just can't figure out what.

Any help????  Please!!!

Alexia

// file consists of a series of strings, each 24 characters long - padded if necessary, in the following format:
// #1234567^1234567^12^1234
// padchar is "?"
// need to retrieve the 24 character string if found
// need to make sure when searching for #123 that #123^ is found rather than #1234567^ etc.
const
  BufferSize = $8001;
var
  pBuf,pEnd,pScan,pPos: pChar;
  Filesize: LongInt;
  BytesRemaining: LongInt;
  BytesToRead: Integer;
  SearchFor: pChar;
  FindLen: LongInt;
  S: Array [0..23] of Char;
  NDB,FoundStr: String;
  StrIdx: Word;
  PartialMatch: Boolean;
begin
  FindLen := 24;

  Result := '';  //assume failure
  if (Length(forString)=0) then Exit;
  SearchFor := NIL;
  pBuf := NIL;

  System.Reset(ConvertFile,1);
  try
    //allocate memory for buffer
    GetMem(pBuf,BufferSize);
    Filesize := System.Filesize(ConvertFile);

    //allocate memory for pchar search string
    SearchFor := StrAlloc(Length(forString)+1);
    StrPCopy(SearchFor,forString);

    BytesRemaining := Filesize;
    pPos := NIL;
    PartialMatch := FALSE;
    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
      try
        BlockRead(ConvertFile,pBuf^,BytesToRead,BytesToRead);
      except
        on e: EInOutError do begin
          MessageDlg(E.Message,mtError,[mbOK],0);  //here is where I get the File Access Denied
          Exit;
          end;
        end;
      pEnd := @pBuf[BytesToRead];
      pEnd^ := #0;
      //find string
      pScan := pBuf;
      While pScan<pEnd do begin
        pPos := StrPos(pScan,SearchFor);  //search for string
        if (pPos<>NIL) then begin   //possibly found it
          StrLCopy(S,pPos,FindLen);
          FoundStr := String(S);    // ex: #12345^01001a^36^345????
          StrIdx := 1;
          NDB := '';
          While FoundStr[StrIdx]<>'^' do begin  //NDB would be #12345
            NDB := NDB+FoundStr[StrIdx];
            Inc(StrIdx);
            end;
          if forString=NDB then begin
            Delete(FoundStr,1,1);  //12345^01001a^36^345????
            While FoundStr[Length(FoundStr)]=PadChar do Delete(FoundStr,Length(FoundStr),1); //12345^01001a^36^345
            Result := FoundStr;
            break;
            end
          else PartialMatch := TRUE;
          end;
        if PartialMatch then begin   //move past to next string if looking for #123, not #12345
          pScan := pPos+FindLen;
          PartialMatch := FALSE
          end
        else begin
          pScan := StrEnd(pScan);
          Inc(pScan);
          end;
        end;
      if pPos<>NIL then break;
      BytesRemaining := BytesRemaining-BytesToRead;
      if BytesRemaining>0 then begin
        Seek(ConvertFile,FilePos(ConvertFile)-Length(forString));
        BytesRemaining := BytesRemaining+Length(forString);
        end;
      end;
  finally
    if SearchFor<>NIL then StrDispose(SearchFor);
    if pBuf<>NIL then FreeMem(pBuf,BufferSize);
    end;
end;
alexiatAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

BlackTigerXCommented:
try calling

CloseFile(ConvertFile)

on the finally part...

finally
  CloseFile(ConvertFile);
    if SearchFor<>NIL then StrDispose(SearchFor);
    if pBuf<>NIL then FreeMem(pBuf,BufferSize);
end;
0
alexiatAuthor Commented:
I believe System.Reset first closes and then reopens the file; however, I tried adding an additional CloseFile as you suggested and the same problem exists.
0
wavgetCommented:
Set the FileMode variable

From the Help File:

Indicates the access mode on typed and untyped files opened by the Reset procedure.

Unit

System

Category

I/O routines

var FileMode: Byte = 2;

Description

The FileMode variable determines the access mode to use when typed and untyped files (not text files) are opened using the Reset procedure.

The default FileMode is 2 (Read/Write access). Assigning another value to FileMode causes all subsequent Resets to use that mode. The SysUtils unit declares a number of file open mode constants that can be assigned to the FileMode variable.

Note:      Be sure to reset FileMode before calling Reset with a read-only file. Even if you are only reading from the file, the default FileMode value (Read/Write access) will cause an attempt to open a read-only file to fail.

Warning:      FileMode is declared as a variable, not as a threadvar. Therefore this variable is not thread-safe.

In other words, FileMode := fmOpenRead; before you open a read-only file will do the trick.

D2.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
alexiatAuthor Commented:
Jeez, I knew it would be something simple.  I set the Filemode in FormShow but not in the subsequent Reset.  Your warning is important and something I didn't know.  Thanks.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.