Файловая переменная должна быть явно инициализирована ("открыта") посредством вызова соответствующей операции или функции:
VAR f: File
f := Open(name)
В некоторых системах различается открытие существующего и нового файлов:
- f := Old(name)
- f := New(name)
Набор объявлений типов, переменных и заголовков процедур (сигнатур) называется определением (definition).
DEFINITION ADruS171_Files; TYPE File = POINTER TO RECORD END; Rider = EXTENSIBLE RECORD eof-: BOOLEAN END; PROCEDURE Close (VAR f: File); PROCEDURE New (name: ARRAY OF CHAR): File; PROCEDURE Old (name: ARRAY OF CHAR): File; PROCEDURE Read (VAR r: Rider; OUT ch: CHAR); PROCEDURE ReadInt (VAR r: Rider; OUT x: INTEGER); PROCEDURE Set (VAR r: Rider; f: File; pos: INTEGER); PROCEDURE Write (VAR r: Rider; ch: CHAR); PROCEDURE WriteInt (VAR r: Rider; x: INTEGER); END ADruS171_Files.
Позиция бегунка скрыта, и поэтому его инвариант не может быть разрушен прямым обращением к его полям. Инвариант выражает тот факт, что позиция бегунка всегда находится в пределах, соответствующих данной последовательности. Истинность инварианта первоначально устанавливается процедурой Set, а в дальнейшем требуется и поддерживается процедурами Read и Write (а также ReadInt и WriteInt).
MODULE ADruS171_Files; (* Реализация модуля Files, сс. 39, 40. *) IMPORT SYSTEM, Log := StdLog; CONST MaxLength = 4096; TYPE File* = POINTER TO RECORD len: INTEGER; a: ARRAY MaxLength OF CHAR END; Rider* = EXTENSIBLE RECORD (* 0 <= pos <= f.len <= MaxLength *) f: File; pos: INTEGER; eof-: BOOLEAN END; PROCEDURE New* ( name: ARRAY OF CHAR ): File; VAR f: File; BEGIN NEW(f); f.len := 0; RETURN f END New; PROCEDURE Old* ( name: ARRAY OF CHAR ): File; VAR f: File; BEGIN HALT( 126 ); RETURN f END Old; PROCEDURE Close* ( VAR f: File ); BEGIN END Close; PROCEDURE Set* ( VAR r: Rider; f: File; pos: INTEGER ); BEGIN ASSERT( f # NIL ); r.f := f; r.eof := FALSE; IF r.pos < 0 THEN r.pos := 0 ELSIF pos > f.len THEN r.pos := f.len ELSE r.pos := pos END END Set; PROCEDURE Write* ( VAR r: Rider; ch: CHAR ); BEGIN ASSERT( r.pos <= r.f.len ); IF r.pos < MaxLength THEN r.f.a[ r.pos ] := ch; INC( r.pos ); IF r.pos > r.f.len THEN INC( r.f.len ) END ELSE r.eof := TRUE END END Write; PROCEDURE Read* ( VAR r: Rider; OUT ch: CHAR ); BEGIN IF r.pos < r.f.len THEN ch := r.f.a[ r.pos ]; INC( r.pos ) ELSE r.eof := TRUE END END Read; (* следующие две процедуры используются в сортировках слиянием: *) PROCEDURE WriteInt* ( VAR r: Rider; x: INTEGER ); VAR u: RECORD [union] x: INTEGER; a: ARRAY 2 OF CHAR; END; BEGIN u.x := x; Write( r, u.a[ 0 ] ); Write( r, u.a[ 1 ] ); END WriteInt; PROCEDURE ReadInt* ( VAR r: Rider; OUT x: INTEGER ); VAR u: RECORD [union] x: INTEGER; a: ARRAY 2 OF CHAR; END; BEGIN Read( r, u.a[ 0 ] ); Read( r, u.a[ 1 ] ); x := u.x; END ReadInt; END ADruS171_Files.