Skip to main content

A.8 Sequential and Direct Files

danger

This Reference Manual output has not been verified, and may contain omissions or errors. Report any problems on the tracking issue

Static Semantics

1/2

Two kinds of access to external files are defined in this subclause: sequential access and direct access. The corresponding file types and the associated operations are provided by the generic packages Sequential_IO and Direct_IO. A file object to be used for sequential access is called a sequential file, and one to be used for direct access is called a direct file. Access to stream files is described in A.12.1.

2

For sequential access, the file is viewed as a sequence of values that are transferred in the order of their appearance (as produced by the program or by the external environment). When the file is opened with mode In_File or Out_File, transfer starts respectively from or to the beginning of the file. When the file is opened with mode Append_File, transfer to the file starts after the last element of the file.

2.a
discussion

Adding stream I/O necessitates a review of the terminology. In Ada 83, sequential' implies both the access method (purely sequential — that is, no indexing or positional access) and homogeneity. Direct access includes purely sequential access and indexed access, as well as homogeneity. In Ada 95, streams allow purely sequential access but also positional access to an individual element, and are heterogeneous. We considered generalizing the notion of sequential file' to include both Sequential_IO and Stream_IO files, but since streams allow positional access it seems misleading to call them sequential files. Or, looked at differently, if the criterion for calling something a sequential file is whether it permits (versus requires) purely sequential access, then one could just as soon regard a Direct_IO file as a sequential file.

2.b

It seems better to regard sequential file' as meaning only permitting purely sequential access'; hence we have decided to supplement sequential access' and direct access' with a third category, informally called access to streams'. (We decided against the term stream access' because of possible confusion with the Stream_Access type declared in one of the stream packages.)

3

For direct access, the file is viewed as a set of elements occupying consecutive positions in linear order; a value can be transferred to or from an element of the file at any selected position. The position of an element is specified by its index, which is a number, greater than zero, of the implementation-defined integer type Count. The first element, if any, has index one; the index of the last element, if any, is called the current size; the current size is zero if there are no elements. The current size is a property of the external file.

4

An open direct file has a current index, which is the index that will be used by the next read or write operation. When a direct file is opened, the current index is set to one. The current index of a direct file is a property of a file object, not of an external file.

Wording Changes from Ada 95

4.a/2

Italicized “stream file” to clarify that this is another kind of file.

A.8.1 The Generic Package Sequential_IO

Static Semantics

1

The generic library package Sequential_IO has the following declaration:

2/5

with Ada.IO_Exceptions; generic type Element_Type(<>) is private; package Ada.Sequential_IO with Global => in out synchronized is 3 type File_Type is limited private; 4 type File_Mode is (In_File, Out_File, Append_File); 5 -- File management 6 procedure Create(File : in out File_Type; Mode : in File_Mode := Out_File; Name : in String := ""; Form : in String := ""); 7 procedure Open (File : in out File_Type; Mode : in File_Mode; Name : in String; Form : in String := ""); 8 procedure Close (File : in out File_Type); procedure Delete(File : in out File_Type); procedure Reset (File : in out File_Type; Mode : in File_Mode); procedure Reset (File : in out File_Type); 9 function Mode (File : in File_Type) return File_Mode; function Name (File : in File_Type) return String; function Form (File : in File_Type) return String; 10 function Is_Open(File : in File_Type) return Boolean; 10.1/5

procedure Flush (File : in File_Type) with Global => overriding in out File; 11 -- Input and output operations 12/5

procedure Read (File : in File_Type; Item : out Element_Type) with Global => overriding in out File; procedure Write (File : in File_Type; Item : in Element_Type) with Global => overriding in out File; 13 function End_Of_File(File : in File_Type) return Boolean; 14 -- Exceptions 15 Status_Error : exception renames IO_Exceptions.Status_Error; Mode_Error : exception renames IO_Exceptions.Mode_Error; Name_Error : exception renames IO_Exceptions.Name_Error; Use_Error : exception renames IO_Exceptions.Use_Error; Device_Error : exception renames IO_Exceptions.Device_Error; End_Error : exception renames IO_Exceptions.End_Error; Data_Error : exception renames IO_Exceptions.Data_Error; 15.1/5

package Wide_File_Names is 15.2/5 -- File management 15.3/5 procedure Create(File : in out File_Type; Mode : in File_Mode := Out_File; Name : in Wide_String := ""; Form : in Wide_String := ""); 15.4/5 procedure Open (File : in out File_Type; Mode : in File_Mode; Name : in Wide_String; Form : in Wide_String := ""); 15.5/5 function Name (File : in File_Type) return Wide_String; 15.6/5 function Form (File : in File_Type) return Wide_String; 15.7/5 end Wide_File_Names; 15.8/5

package Wide_Wide_File_Names is 15.9/5 -- File management 15.10/5 procedure Create(File : in out File_Type; Mode : in File_Mode := Out_File; Name : in Wide_Wide_String := ""; Form : in Wide_Wide_String := ""); 15.11/5 procedure Open (File : in out File_Type; Mode : in File_Mode; Name : in Wide_Wide_String; Form : in Wide_Wide_String := ""); 15.12/5 function Name (File : in File_Type) return Wide_Wide_String; 15.13/5 function Form (File : in File_Type) return Wide_Wide_String; 15.14/5 end Wide_Wide_File_Names; 16 private ... -- not specified by the language end Ada.Sequential_IO;

17/2

The type File_Type needs finalization (see 7.6) in every instantiation of Sequential_IO.

Incompatibilities With Ada 83

17.a

The new enumeration element Append_File may introduce upward incompatibilities. It is possible that a program based on the assumption that File_Mode'Last = Out_File will be illegal (e.g., case statement choice coverage) or execute with a different effect in Ada 95.

17.a.1/2
This paragraph was deleted.{8652/0097}

Incompatibilities With Ada 95

17.b/2
correction

Amendment File_Type in an instance of Sequential_IO is defined to need finalization. If the restriction No_Nested_Finalization (see D.7) applies to the partition, and File_Type does not have a controlled part, it will not be allowed in local objects in Ada 2005 whereas it would be allowed in original Ada 95. Such code is not portable, as another Ada compiler may have a controlled part in File_Type, and thus would be illegal.

Incompatibilities With Ada 2012

17.c/5

Corrigendum: The Flush procedure is newly added to Ada.Sequential_IO. Therefore, a use clause conflict is possible; see the introduction of Annex A for more on this topic.

17.d/5

The Wide_File_Names and Wide_Wide_File_Names nested packages are newly added to Ada.Sequential_IO. Therefore, a use clause conflict is possible; see the introduction of Annex A for more on this topic.

A.8.2 File Management

Static Semantics

1/5

The procedures and functions described in this subclause provide for the control of external files; their declarations are repeated in each of the packages for sequential, direct, text, and stream input-output. For text input-output, the procedures Create, Open, and Reset have additional effects described in A.10.2.

2

procedure Create(File : in out File_Type; Mode : in File_Mode := default_mode; Name : in String := ""; Form : in String := "");

3/2

Establishes a new external file, with the given name and form, and associates this external file with the given file. The given file is left open. The current mode of the given file is set to the given access mode. The default access mode is the mode Out_File for sequential, stream, and text input-output; it is the mode Inout_File for direct input-output. For direct access, the size of the created file is implementation defined.

3.a/4
ramification

For a direct file, the initial value of current index is 1 (see A.8).

4

A null string for Name specifies an external file that is not accessible after the completion of the main program (a temporary file). A null string for Form specifies the use of the default options of the implementation for the external file.

5

The exception Status_Error is propagated if the given file is already open. The exception Name_Error is propagated if the string given as Name does not allow the identification of an external file. The exception Use_Error is propagated if, for the specified mode, the external environment does not support creation of an external file with the given name (in the absence of Name_Error) and form.

6

procedure Open(File : in out File_Type; Mode : in File_Mode; Name : in String; Form : in String := "");

7

Associates the given file with an existing external file having the given name and form, and sets the current mode of the given file to the given mode. The given file is left open.

7.a/4
ramification

For a direct file, the initial value of current index is 1 (see A.8).

8

The exception Status_Error is propagated if the given file is already open. The exception Name_Error is propagated if the string given as Name does not allow the identification of an external file; in particular, this exception is propagated if no external file with the given name exists. The exception Use_Error is propagated if, for the specified mode, the external environment does not support opening for an external file with the given name (in the absence of Name_Error) and form.

9

procedure Close(File : in out File_Type);

10

Severs the association between the given file and its associated external file. The given file is left closed. In addition, for sequential files, if the file being closed has mode Out_File or Append_File, then the last element written since the most recent open or reset is the last element that can be read from the file. If no elements have been written and the file mode is Out_File, then the closed file is empty. If no elements have been written and the file mode is Append_File, then the closed file is unchanged.

11

The exception Status_Error is propagated if the given file is not open.

12

procedure Delete(File : in out File_Type);

13

Deletes the external file associated with the given file. The given file is closed, and the external file ceases to exist.

14

The exception Status_Error is propagated if the given file is not open. The exception Use_Error is propagated if deletion of the external file is not supported by the external environment.

15

procedure Reset(File : in out File_Type; Mode : in File_Mode); procedure Reset(File : in out File_Type);

16/2

Resets the given file so that reading from its elements can be restarted from the beginning of the external file (for modes In_File and Inout_File), and so that writing to its elements can be restarted at the beginning of the external file (for modes Out_File and Inout_File) or after the last element of the external file (for mode Append_File). In particular, for direct access this means that the current index is set to one. If a Mode parameter is supplied, the current mode of the given file is set to the given mode. In addition, for sequential files, if the given file has mode Out_File or Append_File when Reset is called, the last element written since the most recent open or reset is the last element that can be read from the external file. If no elements have been written and the file mode is Out_File, the reset file is empty. If no elements have been written and the file mode is Append_File, then the reset file is unchanged.

17

The exception Status_Error is propagated if the file is not open. The exception Use_Error is propagated if the external environment does not support resetting for the external file and, also, if the external environment does not support resetting to the specified mode for the external file.

18

function Mode(File : in File_Type) return File_Mode;

19

Returns the current mode of the given file.

20

The exception Status_Error is propagated if the file is not open.

21

function Name(File : in File_Type) return String;

22/2

Returns a string which uniquely identifies the external file currently associated with the given file (and may thus be used in an Open operation).

22.a/2
discussion

Retrieving the full path can be accomplished by passing the result of Name to Directories.Full_Name (see A.16). It is important to drop the requirement on Name, as the only way to accomplish this requirement given that the current directory can be changed with package Directories is to store the full path when the file is opened. That's expensive, and it's better for users that need the full path to explicitly request it.

23

The exception Status_Error is propagated if the given file is not open. The exception Use_Error is propagated if the associated external file is a temporary file that cannot be opened by any name.

24

function Form(File : in File_Type) return String;

25

Returns the form string for the external file currently associated with the given file. If an external environment allows alternative specifications of the form (for example, abbreviations using default options), the string returned by the function should correspond to a full specification (that is, it should indicate explicitly all options selected, including default options).

26

The exception Status_Error is propagated if the given file is not open.

27

function Is_Open(File : in File_Type) return Boolean;

28/3

Returns True if the file is open (that is, if it is associated with an external file); otherwise, returns False.

28.1/4

procedure Flush(File : in File_Type);

28.2/4

The Flush procedure synchronizes the external file with the internal file (by flushing any internal buffers) without closing the file. For a direct file, the current index is unchanged; for a stream file (see A.12.1), the current position is unchanged.

28.3/4

The exception Status_Error is propagated if the file is not open. The exception Mode_Error is propagated if the mode of the file is In_File.

28.4/5

The nested package Wide_File_Names provides operations equivalent to the operations of the same name of the outer package except that Wide_String is used instead of String for the name and form of the external file.

28.a/5
implementation note

The expectation is that if one opens a file with this subpackage and then requests the name with Name from this subpackage, the result will include the same Wide_Characters that were used to open the file (rather than some encoded form). Since file names are completely implementation-defined, we cannot say this normatively. We have no expectations when retrieving the name of a file opened with this package using the String Name. Similar considerations apply to the nested package Wide_Wide_File_Names (see below).

28.5/5

The nested package Wide_Wide_File_Names provides operations equivalent to the operations of the same name of the outer package except that Wide_Wide_String is used instead of String for the name and form of the external file.

Implementation Permissions

29

An implementation may propagate Name_Error or Use_Error if an attempt is made to use an I/O feature that cannot be supported by the implementation due to limitations in the external environment. Any such restriction should be documented.

Wording Changes from Ada 95

29.a/2

Clarified that Reset affects and depends on the external file.

29.b/2

Removed the requirement for Name to return a full path; this is now accomplished by Directories.Full_Name(Name(File)) (see A.16). This is not documented as an inconsistency, because there is no requirement for implementations to change — the Ada 95 behavior is still allowed, it just is no longer required.

29.c/2

Added text to specify the default mode for a stream file.

Wording Changes from Ada 2012

29.d/4

Procedure Flush is now defined here, so it can be used for all of the I/O packages.

29.e/5

The nested Wide_File_Names and Wide_Wide_File_Names packages are now described here.

A.8.3 Sequential Input-Output Operations

Static Semantics

1

The operations available for sequential input and output are described in this subclause. The exception Status_Error is propagated if any of these operations is attempted for a file that is not open.

2

procedure Read(File : in File_Type; Item : out Element_Type);

3

Operates on a file of mode In_File. Reads an element from the given file, and returns the value of this element in the Item parameter.

3.a
discussion

We considered basing Sequential_IO.Read on Element_Type'Read from an implicit stream associated with the sequential file. However, Element_Type'Read is a type-related attribute, whereas Sequential_IO should take advantage of the particular constraints of the actual subtype corresponding to Element_Type to minimize the size of the external file. Furthermore, forcing the implementation of Sequential_IO to be based on Element_Type'Read would create an upward incompatibility since existing data files written by an Ada 83 program using Sequential_IO might not be readable by the identical program built with an Ada 95 implementation of Sequential_IO.

3.b

An Ada 95 implementation might still use an implementation-defined attribute analogous to 'Read to implement the procedure Read, but that attribute will likely have to be subtype-specific rather than type-related, and it need not be user-specifiable. Such an attribute will presumably be needed to implement the generic package Storage_IO (see A.9).

4

The exception Mode_Error is propagated if the mode is not In_File. The exception End_Error is propagated if no more elements can be read from the given file. The exception Data_Error can be propagated if the element read cannot be interpreted as a value of the subtype Element_Type (see A.13, “Exceptions in Input-Output”).

4.a
discussion

Data_Error need not be propagated if the check is too complex. See A.13, “Exceptions in Input-Output”.

5

procedure Write(File : in File_Type; Item : in Element_Type);

6

Operates on a file of mode Out_File or Append_File. Writes the value of Item to the given file.

7

The exception Mode_Error is propagated if the mode is not Out_File or Append_File. The exception Use_Error is propagated if the capacity of the external file is exceeded.

8

function End_Of_File(File : in File_Type) return Boolean;

9/3

Operates on a file of mode In_File. Returns True if no more elements can be read from the given file; otherwise, returns False.

10

The exception Mode_Error is propagated if the mode is not In_File.

A.8.4 The Generic Package Direct_IO

Static Semantics

1

The generic library package Direct_IO has the following declaration:

2/5

with Ada.IO_Exceptions; generic type Element_Type is private; package Ada.Direct_IO with Global => in out synchronized is 3 type File_Type is limited private; 4 type File_Mode is (In_File, Inout_File, Out_File); type Count is range 0 .. implementation-defined; subtype Positive_Count is Count range 1 .. Count'Last; 5 -- File management 6 procedure Create(File : in out File_Type; Mode : in File_Mode := Inout_File; Name : in String := ""; Form : in String := ""); 7 procedure Open (File : in out File_Type; Mode : in File_Mode; Name : in String; Form : in String := ""); 8 procedure Close (File : in out File_Type); procedure Delete(File : in out File_Type); procedure Reset (File : in out File_Type; Mode : in File_Mode); procedure Reset (File : in out File_Type); 9 function Mode (File : in File_Type) return File_Mode; function Name (File : in File_Type) return String; function Form (File : in File_Type) return String; 10 function Is_Open(File : in File_Type) return Boolean; 10.1/5

procedure Flush (File : in File_Type) with Global => overriding in out File; 11 -- Input and output operations 12/5

procedure Read (File : in File_Type; Item : out Element_Type; From : in Positive_Count) with Global => overriding in out File; procedure Read (File : in File_Type; Item : out Element_Type) with Global => overriding in out File; 13/5

procedure Write(File : in File_Type; Item : in Element_Type; To : in Positive_Count) with Global => overriding in out File; procedure Write(File : in File_Type; Item : in Element_Type) with Global => overriding in out File; 14/5

procedure Set_Index(File : in File_Type; To : in Positive_Count) with Global => overriding in out File; 15 function Index(File : in File_Type) return Positive_Count; function Size (File : in File_Type) return Count; 16 function End_Of_File(File : in File_Type) return Boolean; 17 -- Exceptions 18 Status_Error : exception renames IO_Exceptions.Status_Error; Mode_Error : exception renames IO_Exceptions.Mode_Error; Name_Error : exception renames IO_Exceptions.Name_Error; Use_Error : exception renames IO_Exceptions.Use_Error; Device_Error : exception renames IO_Exceptions.Device_Error; End_Error : exception renames IO_Exceptions.End_Error; Data_Error : exception renames IO_Exceptions.Data_Error; 18.1/5

package Wide_File_Names is 18.2/5 -- File management 18.3/5 procedure Create(File : in out File_Type; Mode : in File_Mode := Inout_File; Name : in Wide_String := ""; Form : in Wide_String := ""); 18.4/5 procedure Open (File : in out File_Type; Mode : in File_Mode; Name : in Wide_String; Form : in Wide_String := ""); 18.5/5 function Name (File : in File_Type) return Wide_String; 18.6/5 function Form (File : in File_Type) return Wide_String; 18.7/5 end Wide_File_Names; 18.8/5

package Wide_Wide_File_Names is 18.9/5 -- File management 18.10/5 procedure Create(File : in out File_Type; Mode : in File_Mode := Inout_File; Name : in Wide_Wide_String := ""; Form : in Wide_Wide_String := ""); 18.11/5 procedure Open (File : in out File_Type; Mode : in File_Mode; Name : in Wide_Wide_String; Form : in Wide_Wide_String := ""); 18.12/5 function Name (File : in File_Type) return Wide_Wide_String; 18.13/5 function Form (File : in File_Type) return Wide_Wide_String; 18.14/5 end Wide_Wide_File_Names; 19 private ... -- not specified by the language end Ada.Direct_IO;

19.a
reason

The Element_Type formal of Direct_IO does not have an unknown_discriminant_part (unlike Sequential_IO) so that the implementation can make use of the ability to declare uninitialized variables of the type.

20/2

The type File_Type needs finalization (see 7.6) in every instantiation of Direct_IO.

20.a.1/2
This paragraph was deleted.{8652/0097}

Incompatibilities With Ada 95

20.a/2
correction

Amendment File_Type in an instance of Direct_IO is defined to need finalization. If the restriction No_Nested_Finalization (see D.7) applies to the partition, and File_Type does not have a controlled part, it will not be allowed in local objects in Ada 2005 whereas it would be allowed in original Ada 95. Such code is not portable, as another Ada compiler may have a controlled part in File_Type, and thus would be illegal.

Incompatibilities With Ada 2012

20.b/5

Corrigendum: The Flush procedure is newly added to Ada.Direct_IO. Therefore, a use clause conflict is possible; see the introduction of Annex A for more on this topic.

20.c/5

The Wide_File_Names and Wide_Wide_File_Names nested packages are newly added to Ada.Direct_IO. Therefore, a use clause conflict is possible; see the introduction of Annex A for more on this topic.

A.8.5 Direct Input-Output Operations

Static Semantics

1

The operations available for direct input and output are described in this subclause. The exception Status_Error is propagated if any of these operations is attempted for a file that is not open.

2

procedure Read(File : in File_Type; Item : out Element_Type; From : in Positive_Count); procedure Read(File : in File_Type; Item : out Element_Type);

3

Operates on a file of mode In_File or Inout_File. In the case of the first form, sets the current index of the given file to the index value given by the parameter From. Then (for both forms) returns, in the parameter Item, the value of the element whose position in the given file is specified by the current index of the file; finally, increases the current index by one.

4

The exception Mode_Error is propagated if the mode of the given file is Out_File. The exception End_Error is propagated if the index to be used exceeds the size of the external file. The exception Data_Error can be propagated if the element read cannot be interpreted as a value of the subtype Element_Type (see A.13).

5

procedure Write(File : in File_Type; Item : in Element_Type; To : in Positive_Count); procedure Write(File : in File_Type; Item : in Element_Type);

6

Operates on a file of mode Inout_File or Out_File. In the case of the first form, sets the index of the given file to the index value given by the parameter To. Then (for both forms) gives the value of the parameter Item to the element whose position in the given file is specified by the current index of the file; finally, increases the current index by one.

7

The exception Mode_Error is propagated if the mode of the given file is In_File. The exception Use_Error is propagated if the capacity of the external file is exceeded.

8

procedure Set_Index(File : in File_Type; To : in Positive_Count);

9

Operates on a file of any mode. Sets the current index of the given file to the given index value (which may exceed the current size of the file).

10

function Index(File : in File_Type) return Positive_Count;

11

Operates on a file of any mode. Returns the current index of the given file.

12

function Size(File : in File_Type) return Count;

13

Operates on a file of any mode. Returns the current size of the external file that is associated with the given file.

14

function End_Of_File(File : in File_Type) return Boolean;

15/3

Operates on a file of mode In_File or Inout_File. Returns True if the current index exceeds the size of the external file; otherwise, returns False.

16

The exception Mode_Error is propagated if the mode of the given file is Out_File.

17

NOTE Append_File mode is not supported for the generic package Direct_IO.