跳转到内容

Ada 编程/库/Ada.Streams.Stream_IO

来自维基教科书,开放的书籍,构建开放的世界

Ada. Time-tested, safe and secure.
Ada.经久考验,安全可靠。

此语言特性从 Ada 95 开始可用。

Ada.Streams.Stream_IO 是自 Ada 95 以来 预定义语言环境 的一个单元。

“包 Sequential_IO 和 Direct_IO 对于某些应用程序而言不够灵活,因为它们只处理同构文件。”Ada 95 概述:附录 A.4.1 流输入输出

“[序列化是] 将对象(包括它引用的任何对象)的完整状态写入输出流,然后在稍后时间从输入流读取其序列化状态以重新创建该对象的能力。”Java 概览,David Flanagan,第二版,O’Reilly & Associates, Inc.,1997,第 97 页。

流是一个可以消费或产生原始数据元素的实体,通常是字节。

Ada 的解决方案

[编辑 | 编辑源代码]

与 Java 类似,Ada 95 提供了包 Ada.Streams 来允许包含来自可能不同类型的值的元素序列,并允许对这些值进行顺序访问。

  • 过程 Write
  • 过程 Read

每种类型都有一个默认的编码和写入过程,由属性 T'Write 命名,以及一个默认的读取和解码过程,由属性 T'Read 命名。

例如,假设输入文件 mixed.data 包含几个组内部形式的 Float 值,每组前面都有一个 Integer 值,给出该组中的值数量。以下程序将每组的总和以文本形式写入标准输出文件(Ada 作为第二语言,第二版,Cohen,第 794 页 - 从勘误表中更正)

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;

用于有限或用户定义类型的流

[编辑 | 编辑源代码]

程序员可以为其默认过程不提供所需行为的类型覆盖 'Write 和 'Read 属性。这些类型通常是访问类型或具有访问类型子组件的复合类型。

通常,程序员不会直接调用操纵原始数据序列的 Read 和 Write 过程。相反,程序员

  1. 为类型创建读写过程
  2. 将过程与相应的属性关联

编码日期记录(来自 Ada 95 概述,附录 A.4.1,第 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;

然后,程序员正常创建输出文件,并获得对关联日期流的访问权限。

  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);

要输出数据,程序员在要写入的日期值上调用 Date_Record 的 Write 属性

Date_Record'Write(Date_Stream, Some_Date);

对于像 Date_Record 这样的简单记录,预定义的 Write 属性只是按顺序调用每个组件的写入属性。

程序员可以提供一个 Write 版本来将月份名称输出为,例如,整数

首先,定义日期写入过程并关联 'Write 属性

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;

请注意,我们没有重新定义 Date_Record'Write,而是简单地重新定义了 Month_Name'Write,这将被间接调用。

--                     Standard Ada library specification
--   Copyright (c) 2003-2018 Maxim Reznik <[email protected]>
--   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_IO is

   type Stream_Access is access all Root_Stream_Type'Class;

   type File_Type is limited private;

   type File_Mode is (In_File, Out_File, Append_File);

   type    Count          is range 0 .. implementation_defined;
   subtype Positive_Count is Count range 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 file
   procedure 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 file
   procedure 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 file

   procedure 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;

维基教科书

[编辑 | 编辑源代码]

外部示例

[编辑源代码]

Ada 参考手册

[编辑 | 编辑源代码]

开源实现

[编辑 | 编辑源代码]

FSF GNAT

drake

华夏公益教科书