Turbo Pascal 2.0 course cover
← Back to Courses
module
21

Files

Introduction

Everything a program has worked out vanishes when it ends. Warehouse needs to remember things between runs: the levels themselves, and the best score on each. Programs keep things on the disc in files - the same kind of thing as the .PAS files you save from the editor - and Pascal's files are built so that a file of levels is simply a list of level records, on the disc.

A File Of Records

A file type is declared as a file of some type:

var
  F: file of Level;

F is not the file itself; it is the program's handle on one. Four steps turn it into a real file on the disc:

Assign(F, 'LEVELS.DAT');
Rewrite(F);
Write(F, L);
Close(F);
  • Assign gives the handle a file name. Names follow the disc's rules - eight characters, a dot, a three-letter type.
  • Rewrite creates the file, empty. If a file of that name already exists, its contents are thrown away.
  • Write(F, L) adds the record L to the end of the file.
  • Close finishes. Always close a file you have written: Borland's manual warns that otherwise the disc's directory may not be brought up to date, and data can be lost.

To read it back:

Reset(F);
while not Eof(F) do
begin
  Read(F, L);
  ...
end;
Close(F);

Reset opens an existing file at its beginning. Read(F, L) reads the next record into L. Eof(F) - end of file - is true when there are no more.

Any Record, In Any Order

Every record in a file of records is the same size, so Turbo can go straight to any one of them. The records are numbered from 0:

  • Seek(F, 2) moves to record 2 - the third.
  • FilePos(F) says which record is next.
  • FileSize(F) says how many there are.

And you can change one record without touching the rest: Seek to it, Read it, change it, Seek back - the Read moved you on - and Write it. That is how Warehouse will update a best score.

Text Files

A file of type Text holds lines of characters, like the files the editor saves. Writeln and Readln work on it when you give them the file first:

var
  T: Text;
  S: string[40];
...
Writeln(T, 'Push every crate');
Readln(T, S);

Text files are read from the start, a line at a time. They are the right thing for anything a person might want to read, and the wrong thing for records.

When The File Is Not There

Reset of a file that does not exist stops the program:

I/O error 01, PC=00C5
Program aborted

A program that has to cope - "is there a scores file yet?" - can turn the check off around the Reset and look for itself:

{$I-}
Reset(F);
{$I+}
if IOresult = 0 then
  Writeln('Found it')
else
  Writeln('Not there');

With {$I-}, a failed Reset does not stop the program; IOresult then says what happened - 0 if all was well, a number if not (1 for a missing file). Turn the check back on straight afterwards with {$I+}.

A file you no longer want goes with Erase(F) (close it first). And remember that every file costs at least 2k of disc (S6).

The Code

program LevelFile;
type
  Str20 = string[20];
  Level = record
    Name: Str20;
    Best: Integer;
  end;
var
  F: file of Level;
  L: Level;
  I: Integer;
  S: Str20;
begin
  Assign(F, 'LEVELS.DAT');
  Rewrite(F);
  for I := 1 to 3 do
  begin
    Str(I, S);
    L.Name := 'Level ' + S;
    L.Best := I * 10;
    Write(F, L);
  end;
  Close(F);
  Reset(F);
  Writeln(FileSize(F), ' levels');
  while not Eof(F) do
  begin
    Read(F, L);
    Writeln(L.Name, ' best ', L.Best);
  end;
  Close(F);
end.

Starting from

Turbo freshly started, Y, a new work file called LFILE.

What you should see

3 levels
Level 1 best 10
Level 2 best 20
Level 3 best 30

and afterwards D lists LEVELS DAT on the disc.

Change One Thing

  • Put Seek(F, 2); just after the line that prints how many levels there are. Which levels are printed now?
  • Put Write(FilePos(F), ': '); just before Read(F, L);. What numbers appear?
  • Just before Reset(F);, add Assign(F, 'NOSUCH.DAT');. What happens, and where does ESC take you?

Exercises

21.1 Write three lines of advice to a text file called NOTES.TXT, then read the file back and print it.

21.2 After writing the three levels, change level 2's best score to 15 using Seek, then print all three.

21.3 Write a program that says whether a file called SCORES.DAT exists, without stopping if it does not.

Worked solutions are in Appendix II.

When It Goes Wrong

SymptomCause
I/O error 01 at a ResetThe file does not exist - or its name in Assign is not the one on the disc.
A file that was there is emptyRewrite was used on it, which empties it. Use Reset to read.
A Seek lands one record outRecords are numbered from 0. Record 1 is the second.
Changing a record wrote over the next oneRead moves on a record; Seek back before you Write.
The disc is filling upEvery file costs at least 2k. Erase or ERA what you do not need.

Summary

file of T holds records of type T on the disc: Assign a name, Rewrite to create or Reset to open, Write and Read, Close. Seek, FilePos and FileSize number records from 0, so any record can be read or changed. Text files hold lines, with Writeln and Readln. A missing file is I/O error 01 - unless {$I-} is on and you check IOresult.

Next

S22, Pointers - making new variables while the program runs, and a list that grows and shrinks: the heart of undo.

Get the Newsletter

New guides, disk images and community finds, roughly once a quarter. No spam, we promise, this isn't Tatung's marketing department.
Your subscription could not be saved. Please try again.
Your subscription has been successful.

Newsletter

Subscribe to our newsletter and stay updated.