Ada Programming/Libraries/Ada.Streams.Stream_IO
This language feature is available from Ada 95 on.
Ada.Streams.Stream_IO is a unit of the Predefined Language Environment since Ada 95.
Description
[edit | edit source]“The packages Sequential_IO and Direct_IO have not proved to be sufficiently flexible for some applications because they process only homogenous files.” Ada 95 Rationale: Annex A.4.1 Stream Input and Output
“[Serialization is] the ability to write the complete state of an object (including any objects it refers to) to an output stream, and then recreate that object at some later time by reading its serialized state from an input stream.” Java in a Nutshell, David Flanagan, 2nd ed, O’Reilly & Associates, Inc., 1997, p. 97.
A stream is an entity that can consume or produce elements of raw data, typically bytes.
Ada's Solution
[edit | edit source]Like Java, Ada 95 provides package Ada.Streams to allow a sequence of elements comprising values from possibly different types and allowing sequential access to these values.
- procedure Write
- procedure Read
Every type has a default encode–and–write procedure named by the attribute T'Write and a default read–and–decode procedure named by the attribute T'Read.
For example, suppose an input file mixed.data contains several groups of Float values in internal form, with each group preceded by an Integer value giving the number of values in the group. The following program writes the sum of each group in textual form to the standard output file (Ada as a Second Language, 2nd ed., Cohen, p 794 – corrected from Errata):
with Ada.Float_Text_IO;
with Ada.Streams.Stream_IO;
procedure Sum_Groups is
Input_File : Ada.Streams.Stream_IO.File_Type;
Input_Stream : Ada.Streams.Stream_IO.Stream_Access;
Group_Size : Integer; -- Number of data items
Sum : Float; -- Sum of data items
Next : Float; -- Input data item
begin
Ada.Streams.Stream_IO.Open(Input_File,
Ada.Streams.Stream_IO.In_File,
"mixed.data");
Input_Stream := Ada.Streams.Stream_IO.Stream(Input_File);
Process_Group:
while not Ada.Streams.Stream_IO.End_Of_File(Input_File) loop
Integer'Read(Input_Stream, Group_Size);
Sum := 0.0; -- Initialize sum of group
Get_Group_Data:
for I in 1..Group_Size loop
Float'Read(Input_Stream, Next);
Sum := Sum + Next;
end loop Get_Group_Data;
Ada.Float_Text_IO.Put(Sum);
end loop Process_Group;
Ada.Streams.Stream_IO.Close(Input_File);
end Sum_Groups;
Streams for Limited or User-defined Types
[edit | edit source]The programmer can override the 'Write
and 'Read
attributes for types whose default procedures do not provide the desired behavior. These types are typically access types or composite types with access–type subcomponents.
Typically, the programmer does not call the Read and Write procedures manipulating sequences of raw data directly. Instead, the programmer:
- Creates read and write procedures for types
- Associates procedures with corresponding attributes
Example
[edit | edit source]Encoding a date record (from Ada 95 Rationale, Annex A.4.1, p A–27)
type Day_Number is range 1..31;
type Month_Name is (January, February, March, April,
May, June, July, August,
September, October, November, December);
type Date_Record is
record
Day : Day_Number;
Month : Month_Name;
Year : Integer;
end record;
Then, the programmer creates an output file normally, and obtains access to associated date stream.
Some_Date : Date_Record;
Date_File : Ada.Streams.Stream_IO.File_Type;
Date_Stream : Ada.Streams.Stream_IO.Stream_Access;
begin
Ada.Streams.Stream_IO.Create(Date_File);
Date_Stream := Ada.Streams.Stream_IO.Stream(Date_File);
To output the data, the programmer invokes the Write
attribute for the Date_Record
on the value of the date to be written:
Date_Record'Write(Date_Stream, Some_Date);
For a simple record such as Date_Record
the predefined Write
attribute simply calls the write attributes for each component in order.
The programmer can provide a version of Write
to output the month name as, say, an integer:
First, define the date write procedure and associate 'Write
attribute
procedure Date_Write(Stream : access Root_Stream_Type'Class;
Item : in Date_Record) is
begin
Integer'Write(Stream, Item.Day);
Integer'Write(Stream, Month_Name'Pos(Item.Month) + 1);
Integer'Write(Stream, Item.Year);
end Date_Write;
for Date_Record'Write use Date_Write;
Note that, instead of redefining Date_Record'Write
, we could have simply redefined Month_Name'Write
, and this would be called indirectly.
Specification
[edit | edit source]-- Standard Ada library specification -- Copyright (c) 2003-2018 Maxim Reznik <reznikmm@gmail.com> -- Copyright (c) 2004-2016 AXE Consultants -- Copyright (c) 2004, 2005, 2006 Ada-Europe -- Copyright (c) 2000 The MITRE Corporation, Inc. -- Copyright (c) 1992, 1993, 1994, 1995 Intermetrics, Inc. -- SPDX-License-Identifier: BSD-3-Clause and LicenseRef-AdaReferenceManual -- -------------------------------------------------------------------------with
Ada.IO_Exceptions;package
Ada.Streams.Stream_IOis
type
Stream_Accessis
access
all
Root_Stream_Type'Class;type
File_Typeis
limited
private
;type
File_Modeis
(In_File, Out_File, Append_File);type
Countis
range
0 .. implementation_defined;subtype
Positive_Countis
Countrange
1 .. Count'Last; -- Index into file, in stream elements.procedure
Create (File :in
out
File_Type; Mode :in
File_Mode := Out_File; Name :in
String := ""; Form :in
String := "");procedure
Open (File :in
out
File_Type; Mode :in
File_Mode; Name :in
String; Form :in
String := "");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);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;function
Is_Open (File :in
File_Type)return
Boolean;function
End_Of_File (File :in
File_Type)return
Boolean;function
Stream (File :in
File_Type)return
Stream_Access; -- Return stream access for use with T'Input and T'Output -- Read array of stream elements from fileprocedure
Read (File :in
File_Type; Item :out
Stream_Element_Array; Last :out
Stream_Element_Offset; From :in
Positive_Count);procedure
Read (File :in
File_Type; Item :out
Stream_Element_Array; Last :out
Stream_Element_Offset); -- Write array of stream elements into fileprocedure
Write (File :in
File_Type; Item :in
Stream_Element_Array; To :in
Positive_Count);procedure
Write (File :in
File_Type; Item :in
Stream_Element_Array); -- Operations on position within fileprocedure
Set_Index(File :in
File_Type; To :in
Positive_Count);function
Index(File :in
File_Type)return
Positive_Count;function
Size (File :in
File_Type)return
Count;procedure
Set_Mode(File :in
out
File_Type; Mode :in
File_Mode);procedure
Flush(File :in
out
File_Type); -- exceptions 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;private
pragma
Import (Ada, File_Type);end
Ada.Streams.Stream_IO;
See also
[edit | edit source]Wikibook
[edit | edit source]External examples
[edit source]- Search for examples of
Ada.Streams.Stream_IO
in: Rosetta Code, GitHub (gists), any Alire crate or this Wikibook. - Search for posts related to
Ada.Streams.Stream_IO
in: Stack Overflow, comp.lang.ada or any Ada related page.
Ada Reference Manual
[edit | edit source]Ada 95
[edit | edit source]Ada 2005
[edit | edit source]Ada 2012
[edit | edit source]Open-Source Implementations
[edit | edit source]FSF GNAT
- Specification: a-ststio.ads
- Body: a-ststio.adb
drake
- Specification: streams/a-ststio.ads
- Body: streams/a-ststio.adb