跳轉到內容

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 <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_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

華夏公益教科書