A sequential file is one where the items are stored in an order determined by a key field. In the case of a file containing discrete data items such as strings or numbers then the order would be alphabetic or numerical. In the case of a file of records with more than one field the file might be sorted on any one or more of them, for example by ID (primary key) or by any other suitable field.
Proceeding from an example, we define a record type and file format as follows:
type
Tperson=record
name:string[20];
address:string[20];
dateofbirth:TDateTime;
end;
Tpersonfile=file of TPerson;
And some variables:
var
Form1: TForm1;
person:TPerson;
personfile:TPersonfile;
To begin with we will create a serial file, that is one where the records are held and accessed in sequence but where they are not sorted on any key field and the order is random.
We set up a form with some edit controls for text entry and a TDateTimePicker for input, some buttons and a listbox for output:

This routine creates a new file, overwriting any earlier copies.
procedure TForm1.NewButtonClick(Sender: TObject);
begin
if MessageDlg('Do you want to overwrite the file?', mtConfirmation, [mbYes,
mbNo], 0) = mrYes
then
begin
assignfile(personfile,'persons.dat');
rewrite(personfile);
closefile(personfile);
end;
end;
The MessageDlg is used to allow the user to confirm that they want to overwrite the file and thus destroy its contents. You must make sure that the persons.dat file is in the same directory as the program code (or extend the path). Use Notepad to make an empty file and save it as 'persons.dat'.
Improved code using try:
if MessageDlg('Do you want to overwrite the file?', mtConfirmation, [mbYes,
mbNo], 0) = mrYes
then
begin
try
assignfile (personfile,'persons.dat');
rewrite (personfile);
end;
finally
CloseFile(personfile);
end;
end;
The first version of the code for the save button writes a single record into the file. The code shown below will write a record at the end of the file:
procedure TForm1.SaveButtonClick(Sender: TObject);
begin
assignfile(personfile,'persons.dat');
//change file name & path to suit
reset(personfile);
with person do
begin
name:=edit1.Text;
address:=edit2.text;
dateofbirth:=datetimepicker1.Date;
end;
seek(personfile,filesize(personfile));
//find end of file and
write(personfile,person); //add new
record
end;
Notice the use of the seek procedure to find the end of the file before we write a new record into it.
Improved code using try:
begin
try
assignfile(personfile,'persons.dat'); //change file name & path to suit
reset(personfile);
with person do
begin
name:=edit1.Text;
address:=edit2.text;
dateofbirth:=datetimepicker1.Date;
end;
seek(personfile,filesize(personfile)); //find end of file and
write(personfile,person); //add new
record
end; //try
finally
closefile(personfile);
end;
procedure TForm1.DisplayButtonClick(Sender: TObject);
var
lbstring:string;
begin
listbox1.Clear;
assignfile(personfile,'persons.dat'); //change
file name & path to suit
reset(personfile);
while not eof (personfile) do
begin
read(personfile,person);
lbstring:=person.name + ' ' + person.address + ' ' +
datetostr(person.dateofbirth);
listbox1.Items.Add(lbstring);
end;
end;
This is unsophisticated but effective for our purposes here.
To create a sequential file we must place each new item in the correct location within the file. Each time a new record is added to the file we must make sure that it is added at the correct place so that the sequence is maintained. To do this we use two files, the old 'master' file and a new copy that will include the added record in the correct place.
The code to add a new record in the correct place to maintain sequence is now more complex:
procedure TForm1.SaveButtonClick(Sender: TObject);
var
newpersonfile:Tpersonfile;
//could add these to interface declarations as with personfile
newpersonrec, filepersonrec:TPerson;
inserted:Boolean;
begin
inserted:=false;
assignfile(personfile,'persons.dat'); //change
file name & path to suit
reset(personfile);
assignfile(newpersonfile,'newpersons.dat');
//change file name & path to suit
rewrite(newpersonfile);
with newpersonrec do
begin
name:=edit1.Text;
address:=edit2.text;
dateofbirth:=datetimepicker1.Date;
end;
if eof(personfile) then write(newpersonfile,newpersonrec);
//new file
while not eof (personfile) do
begin
read(personfile, filepersonrec);
if (newpersonrec.name < filepersonrec.name) and (not inserted) then
begin
write(newpersonfile, newpersonrec);
//add new record
write(newpersonfile, filepersonrec);
//add file record
inserted:=true;
end
else
write(newpersonfile, filepersonrec);
//not place to insert new record so write file record
if (eof(personfile)) and (not inserted) then
write(newpersonfile,newpersonrec); //where new
items > last in file
end; //while
closefile(personfile);
closefile(newpersonfile);
assignfile(personfile,'persons.dat');
//copy records from new file.
Change file name & path to suit
rewrite(personfile);
//to old file
assignfile(newpersonfile,'newpersons.dat');
//change file name & path to suit
reset(newpersonfile);
while not eof(newpersonfile) do
begin
read(newpersonfile, filepersonrec);
write(personfile,filepersonrec);
end;
closefile(personfile);
closefile(newpersonfile);
assignfile(newpersonfile,'newpersons.dat');
//change file name & path to suit
rewrite(newpersonfile); //empty file
for next time
closefile(newpersonfile);
end;
Alternative code:
procedure TForm1.SaveButtonClick(Sender: TObject);
var
person, newperson:TPerson;
personfile, personfiletemp:TPersonfile;
added:Boolean;
begin
added:=false;
assignfile(personfile,'persons.dat');
reset(personfile);
assignfile(personfiletemp,'personstemp.dat');
rewrite(personfiletemp);
with newperson do
begin
name:=edit1.Text;
address:=edit2.text;
dateofbirth:=datetimepicker1.Date;
end;
while not eof (personfile) do
begin
read(personfile,person);
if newperson.name > person.name then
write (personfiletemp,person)
else
if (newperson.name <= person.name) and (added=false) then
begin
write(personfiletemp,newperson);
write (personfiletemp,person);
added:=true;
end
else
if (newperson.name <= person.name) and (added=true) then
write (personfiletemp,person)
end; //while
if not added then write(personfiletemp,newperson);
closefile(personfile);
closefile(personfiletemp);
assignfile(personfiletemp,'personstemp.dat');
reset(personfiletemp);
assignfile(personfile,'persons.dat');
rewrite(personfile);
while not eof(personfiletemp) do
begin
read(personfiletemp,person);
write(personfile, person);
end;
closefile(personfile);
closefile(personfiletemp);
end;
The code uses a Boolean value to determine whether the new record has been added to the file. When a new record is read from the existing file there are multiple conditions to test:
We could also read the entire file into memory and sort it with the new record included. The process using a sort algorithm looks like this:
procedure TForm1.SaveButtonClick(Sender: TObject);
var
person, newperson:TPerson;
personfile, personfiletemp:TPersonfile;
personarray:array[1..100] of TPerson;
i,j,k,m:integer;
tempPerson:TPerson;
begin
assignfile(personfile,'persons.dat');
reset(personfile);
assignfile(personfiletemp,'personstemp.dat');
rewrite(personfiletemp);
while not eof (personfile) do
begin
read(personfile,person);
write(personfiletemp,person);
end;
with newperson do
begin
name:=edit1.Text;
address:=edit2.text;
dateofbirth:=datetimepicker1.Date;
write(personfiletemp,newperson);
end;
closefile(personfile);
closefile(personfiletemp);
//read temp file into array
assignfile(personfiletemp,'personstemp.dat');
reset(personfiletemp);
i:=0;
while not eof(personfiletemp) do
begin
inc(i);
read(personfiletemp,personarray[i]);
end;
closefile(personfiletemp);
//bubble sort array
for j:= 1 to i-1 do
for k:= j+1 to i do
if personarray[j].name > personarray[k].name then
begin
tempPerson:=personarray[j];
personarray[j]:=personarray[k];
personarray[k]:=tempPerson;
end;
//write temp file to master
assignfile(personfile,'persons.dat');
rewrite(personfile);
for m :=1 to i do
begin
showmessage(inttostr(m));
write (personfile, personarray[m]);
end;
closefile(personfile);
end;
This uses an array to hold the file in memory while it is sorted. The issue here is how large to make the array. Again, the same display procedure will do the job.
As well as adding records to a sequential file we also need to be able to delete them and amend them.
Deleting a record is the reverse of adding a new one. We need to identify the record to be deleted and then skip over it as we write records from the old file to the new one. This turns out to be less complex than the insertion routine because we simply need to compare the current record from the file with the item to be deleted and, if they are not the same, write the record to the new file; if they are the same then the current record will not be written and so will be deleted.
procedure TForm1.deleteClick(Sender: TObject);
var
person:TPerson;
personfile, personfiletemp:TPersonfile;
begin
assignfile(personfile,'persons.dat');
reset(personfile);
assignfile(personfiletemp,'personstemp.dat');
rewrite(personfiletemp);
if not (namebox.text='') then
begin
while not eof (personfile) do
begin
read(personfile, person);
if not (person.name = namebox.Text) then
write(personfiletemp, person);
end;
end
else
showmessage('You must enter a name to delete');
closefile(personfile);
closefile(personfiletemp);
assignfile(personfiletemp,'personstemp.dat');
reset(personfiletemp);
assignfile(personfile,'persons.dat');
rewrite(personfile);
while not eof(personfiletemp) do
begin
read(personfiletemp,person);
write(personfile, person);
end;
closefile(personfile);
closefile(personfiletemp);
end;
A third major operation on file data involves changing fields within a record, as in the case of a balance after new transactions or where an address is changed. In the following code the amendments to a record have been placed in appropriate text boxes, the file is searched for a matching key field and the corresponding record is updated before copying it to a temporary file.
procedure TForm1.amendClick(Sender: TObject);
var
person, amendperson:TPerson;
personfile, personfiletemp:TPersonfile;
begin
assignfile(personfile,'persons.dat');
reset(personfile);
assignfile(personfiletemp,'personstemp.dat');
rewrite(personfiletemp);
if not (namebox.text='') then
begin
while not eof(personfile) do
begin
read(personfile, person);
if person.name=namebox.Text then
begin
with amendperson do
begin
name:=namebox.text;
address:=addressbox.text;
dateofbirth:=datetimepicker1.Date;
end;
write(personfiletemp, amendperson);
end
else
write(personfiletemp, person);
end;
end
else
showmessage('You must enter a name to amend');
closefile(personfile);
closefile(personfiletemp);
assignfile(personfiletemp,'personstemp.dat');
reset(personfiletemp);
assignfile(personfile,'persons.dat');
rewrite(personfile);
while not eof(personfiletemp) do
begin
read(personfiletemp,person);
write(personfile, person);
end;
closefile(personfile);
closefile(personfiletemp);
end;
Rather than implement customised file routines, including insert, delete, merge and modify, it is now more common to put data inside a database and to access it using technologies such as ADO.