Элементарные операции с файлами

Файловая переменная должна быть явно инициализирована ("открыта") посредством вызова соответствующей операции или функции:

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.