File Handling in Pascal
Pascal supports three categories of file variables: text files (TextFile or Text), for human-readable line-based data; typed files (file of RecordType), for fixed-size binary records; and untyped files (file), for raw byte-level access used with fast block operations. Every file operation follows the same basic lifecycle: declare a file variable, Assign it to a filesystem path, open it with Reset (read existing) or Rewrite (create/overwrite), perform reads or writes, then Close it to flush buffers and release the handle.
Cricket analogy: Choosing between a text file, typed file, and untyped file is like choosing between a written scorecard (human-readable, line by line), a structured stats database entry per player (fixed-size typed record), and raw broadcast footage bytes (untyped, just data) — three ways of storing the same match differently.
Text File I/O
Text files are opened with AssignFile/Assign and Reset or Rewrite, then read line-by-line with Readln into string or numeric variables, or written with Writeln. The Eof(f) function checks whether the read position has reached the end of the file, which is the standard way to loop through an unknown number of lines without reading past the last one.
Cricket analogy: Reading a text file line by line with Readln in a loop until Eof is like reading a printed scorecard over-by-over until you reach the final over — you don't know how many overs were bowled until you hit the end.
var
f: TextFile;
line: string;
lineCount: Integer;
begin
AssignFile(f, 'notes.txt');
Reset(f);
lineCount := 0;
while not Eof(f) do
begin
Readln(f, line);
Inc(lineCount);
Writeln(lineCount, ': ', line);
end;
CloseFile(f);
end.Typed and Untyped Files
A typed file, declared as file of TStudentRecord, stores fixed-size binary records sequentially, letting you jump directly to the Nth record with Seek(f, n) since every record occupies exactly the same number of bytes, calculated with SizeOf. Untyped files, declared simply as file, skip Pascal's type checking entirely and are read or written with BlockRead/BlockWrite using a specified buffer size, giving the fastest possible raw throughput for large binary data like images or archives.
Cricket analogy: Jumping straight to the 37th ball's typed record with Seek is like a stats analyst jumping straight to over 6, ball 1 in a fixed-format ball-by-ball database instead of scanning from the first ball.
Typed-file record size is computed automatically with SizeOf(RecordType), so Seek(f, n) positions the file pointer at byte offset n * SizeOf(RecordType) — this is what makes random-access reads and writes to record N possible without reading records 1 through N-1 first.
Error Handling and Best Practices
By default, a failed file operation (like opening a missing file with Reset) halts the program with a runtime error. Wrapping I/O in {$I-} disables this automatic runtime checking, and {$I+} (the default) re-enables it; after an operation performed under {$I-}, calling IOResult returns zero on success or a nonzero error code on failure, letting you handle missing files or disk errors gracefully instead of crashing.
Cricket analogy: Checking IOResult after {$I-} Reset is like a captain checking the pitch report before committing to a batting order — instead of just walking out and being caught off guard by a wet pitch, you check the result code first and adapt.
Forgetting to call CloseFile (or Close) leaves the operating system file handle open and, for files opened with Rewrite, may leave written data stuck in an internal buffer that never gets flushed to disk. Always close every file you assign, ideally guarded with try...finally so it closes even if an error occurs mid-operation.
- Pascal has three file kinds: text files (line-based), typed files (fixed-size records), and untyped files (raw bytes).
- The lifecycle is Assign, Reset/Rewrite, read/write, Close for every file type.
- Text files use Readln/Writeln and the Eof function to detect the end of data.
- Typed files support random access via Seek because every record has an identical size from SizeOf.
- Untyped files use BlockRead/BlockWrite with a buffer size for maximum raw throughput.
- {$I-} disables automatic runtime I/O error halting so IOResult can be checked manually.
- Always close files, ideally in a try...finally block, to flush buffers and release handles.
Practice what you learned
1. Which function checks whether the read position has reached the end of a text file?
2. What makes Seek(f, n) possible on a typed file?
3. What is the purpose of the compiler directive {$I-}?
4. Which procedures are used to read from and write to an untyped file?
5. Why should every opened file be closed with CloseFile?
Was this page helpful?
You May Also Like
Dynamic Memory Management
Understand pointers, the heap, and how to allocate, use, and free dynamic memory safely in Pascal.
Exception Handling in Pascal
Learn how try..except and try..finally let Object Pascal programs handle errors gracefully and guarantee cleanup.
Units and Modular Programming
Learn how Pascal's unit system lets you split large programs into reusable, separately-compiled modules with clean interfaces.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics