流IO (Stream_IO )
流是 字节流 的简称。流IO也和顺序IO一样,它们有着同名的文件模式:In_File, Out_File, Append_File ,即只读文件、只写文件、附加文件。流IO的底层设计使得操作变得简便,相对于顺序IO与直接IO都要方便很多。来看下方例程。
with Ada.Text_IO;
with Ada.Streams;
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
procedure stream_io_test is
File : File_Type;
S : Stream_Access;
data : constant String := "Stream IO!";
type Int_Array is array (Natural range <>) of Integer;
****-- 这两个数字对应字符 ‘A’、 ‘B’
FA : array(1..2) of Integer := (65,66);
begin
Create(File,Out_File,"stream_io_test.txt");
S := Stream(File);
String'Write(S,data);
Int_Array'Write(S,Int_Array(FA));
Set_Mode(File,In_File);
-- 设置文件位置
Set_Index(File,1);
Reset(File,Append_File);
Ada.Text_IO.Put_Line("Offset : " & Index(File)'Img);
Reset(File,In_File);
Block_Read:
declare
Buffer : String(1..64) := (others => Character'First);
-- SEA 与Buffer同体
SEA : Ada.Streams.Stream_Element_Array(1..64) with Address => Buffer'Address;
N : Ada.Streams.Stream_Element_Offset;
begin
-- String'Read(S,Buffer(1..Integer(Size(File)) ));
-- Ada.Text_IO.Put_Line(Buffer(1..18));
Ada.Streams.Read(S.all,SEA,N);
Ada.Text_IO.Put_Line(Buffer(1..Integer(N)));
end Block_Read;
if Is_Open(File) then
Close(File);
end if;
-- 加延时为了能在控制台窗口(Console Window)看到运行结果
delay 100.0;
end stream_io_test;
前面的例程里,读写语句的写法有点意思:
type_name’Read(流指针(Stream_Access),要写入的目标缓存);
type_name’Write(流指针,要拷贝的目标缓存);
Read和Write也是预定义属性,在Ada.Streams包中的私有部分有:
procedure Read_SEA
(S : access Root_Stream_Type'Class;
V : out Stream_Element_Array);
procedure Write_SEA
(S : access Root_Stream_Type'Class;
V : Stream_Element_Array);
for Stream_Element_Array'Read use Read_SEA;
for Stream_Element_Array'Write use Write_SEA;
上方的指派可以称为属性 ( 函数) 重载 ,重载函数的书面格式必须与预定义属性标准一致,否则指派失败。GCC编译器支持所有类型的流读写属性,这是为什么我们在Ada.Streams.Stream_IO包中没有找到任意类型读写实现的机制。Ada.Streams包中,Read_SEA与Write_SEA函数都分别调用了包中的虚函数Read和Write,在Ada.Streams.Stream_IO包中,则定义了这两个虚函数的超越函数(overriding function,也可以称为实函数)实现,只要使用了Stream_IO的File_Type,对任意类型的文件操作都会调用这两个超越函数。