Sequential_IO may be instantiated with either a definite (constrained) or indefinite (unconstrained) type.
For the definite type case, the elements written to the file are simply the memory images of the data values with no control information of any kind. The resulting file should be read using the same type, no validity checking is performed on input.
For the indefinite type case, the elements written consist of two
parts. First is the size of the data item, written as the memory image
of a Interfaces.C.size_t
value, followed by the memory image of
the data value. The resulting file can only be read using the same
(unconstrained) type. Normal assignment checks are performed on these
read operations, and if these checks fail, Data_Error
is
raised. In particular, in the array case, the lengths must match, and in
the variant record case, if the variable for a particular read operation
is constrained, the discriminants must match.
Note that it is not possible to use Sequential_IO to write variable
length array items, and then read the data back into different length
arrays. For example, the following will raise Data_Error
:
package IO is new Sequential_IO (String); F : IO.File_Type; S : String (1..4); ... IO.Create (F) IO.Write (F, "hello!") IO.Reset (F, Mode=>In_File); IO.Read (F, S); Put_Line (S);
On some Ada implementations, this will print hell
, but the program is
clearly incorrect, since there is only one element in the file, and that
element is the string hello!
.
In Ada 95 and Ada 2005, this kind of behavior can be legitimately achieved using Stream_IO, and this is the preferred mechanism. In particular, the above program fragment rewritten to use Stream_IO will work correctly.