Searching Within Files
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, with the selection 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 three (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 the 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 the 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:
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 backwards, but remember that this is less efficient (takes ~50% longer) compared to forward searches.