Searching Within Files

Top  Previous  Next

Discussed in this topic: fd.find.

 

The fd.find method allows you to quickly search through the file from a specified starting position, either in forward or back direction, and locate the Nth instance of a search substring. The method also allows you to specify the search "increment" (step). The search is performed on a currently selected file, and the selection is made through the fd.filenum property.

The search returns the position within the file, counting from 1, where the target occurrence of the substring has been encountered, or 0 if the target occurrence of the substring was not found.

The increment parameter is very important as it allows you to perform two fundamentally different classes of search.

Full text search

Set the increment to 1 and you will search through the entire contents of the file:

 

 

Dim dw As dword

 

'try to find the 2nd occurrence of 'ABC', search forward starting at the beginning of the file

dw=fd.find(1,"ABC",2,FORWARD,1)

If fd.laststatus<>PL_FD_STATUS_OK Then

  'some disk-related error

Else

 

If dw<>0 Then

  'found! process this...

Else

  'not found...

End If

 

 

Since the search substring in the above example — "ABC" — does not have repeating fragments, you can actually set the search increment to 3 (the length of the substring). This will improve the search speed:

 

 

fd.find(1,"ABC",2,FORWARD,3) 'no repeating fragments in the substring, use its length as increment

 

Record-style search

If the file in question is a data table consisting of individual records, then you can arrange for a very efficient search for the record with desired field value. All you need to achieve this is to have record fields occupy fixed offsets within records. For example, supposing you have the data table consisting of records with the following structure:

 

Field name

Offset in bytes*

Length in bytes

Category

+0

1

ID-code

+1

11

Last name

+12

21

First name

+43

21

* with respect to the beginning of the record

 

Each record of this data table occupies 54 bytes, so this will be our step. Three fields — "ID-code", "last name", and first name" are strings which, of course, can have a variable length. To facilitate the use of the fd.find method, each field must reside at a fixed offset relative to the beginning of the record. That is, even if the "ID-code" for a particular record is shorter than the maximum possible field length, the "Last name" field will still be at offset +12. To reflect actual length of the field data, each field of string type starts with a byte that denotes the length of the string, followed by the string data itself:

 

fd_string_field

 

Now let's suppose you want to find a record whose "last name" is "Smith". For this we search starting from file offset 21, which is the offset of the "Last name" field within the record (this assumes that the first record starts right from the beginning of the file, which is usually the case). The search step will be 54 — the size of the record:

 

 

Dim dw As dword

 

'try to find the record with the "Last name" set to "Smith"

dw=fd.find(21,chr(5)+"Smith",1,FORWARD,54) 'notice how we supply the string length

If fd.laststatus<>PL_FD_STATUS_OK Then

  'some disk-related error

Else

 

If dw<>0 Then

  'found- convert into the record number and process...

  dw=dw/54

Else

  'not found...

End If

 

 

You can also search back, but remember that this is less efficient (takes ~ 50% longer) compared to forward searches.