从Ada中的管道读取输入

时间:2018-01-10 12:28:00

标签: file pipe ada

我有一段代码(见下文),它从作为命令行参数给出的文件中读取数据。我想添加一个支持,以便能够从管道读取输入。例如,当前版本将数据读取为main <file_name>,而应该也可以执行第cmd1 | main行。以下是从文件中读取数据的来源:

procedure main is

    File : Ada.Text_IO.File_Type;

begin

   if Ada.Command_Line.Argument_Count /= 1 then

      return;

   else

      Ada.Text_IO.Open (
         File => File,
         Mode => In_File,
         Name => Ada.Command_Line.Argument (1));

      while (not Ada.Text_IO.End_Of_File (File)) loop
         -- Read line using Ada.Text_IO.Get_Line
         -- Process the line
      end loop;

      Ada.Text_IO.Close (File);

end main;

如果我理解正确,管道只是Ada中的非常规文件类型。但是我该如何处理呢?

3 个答案:

答案 0 :(得分:4)

您甚至无需创建文件即可从管道中读取数据。

只是

with Ada.Text_IO;
procedure main is

    begin

      loop
        exit when Ada.Text_IO.End_Of_File;
        Ada.Text_IO.Put_Line("Echo" &Ada.Text_IO.Get_Line);
      end loop;
end main;

之后type ..\src\main.adb | main.exe有效。

答案 1 :(得分:4)

这些似乎都没有真正回答你的问题。管道只是使另一个程序的标准输出成为程序的标准输入,因此您通过读取Standard_Input来读取管道。

函数Current_Input返回File_Type。它最初返回Standard_Input,但调用Set_Input会将其更改为返回传递给Set_Input的任何内容。所以粗略概述了如果没有给出文件,如何从Standard_Input读取,如果是,则从给定文件中读取,如下所示:

File : File_Type;

if Argument_Count > 0 then
   Open (File => File, Name => Argument (1), Mode => In_File);
   Set_Input (File => File);
end if;

All_Lines : loop
   exit All_Lines when End_Of_File (Current_Input);

   Process (Line => Get_Line (Current_Input) );
end loop All_Lines;

答案 2 :(得分:3)

引自the ARM...

  

库包Text_IO具有以下声明:

...
package Ada.Text_IO is
...
   -- Control of default input and output files

   procedure Set_Input (File : in File_Type);
   procedure Set_Output(File : in File_Type);
   procedure Set_Error (File : in File_Type);

   function Standard_Input  return File_Type;
   function Standard_Output return File_Type;
   function Standard_Error  return File_Type;

   function Current_Input   return File_Type;
   function Current_Output  return File_Type;
   function Current_Error   return File_Type;

允许您将默认管道stdin, stdout, stderr作为文件进行操作;要么作为预先打开的文件(输入和输出管道),要么允许您将stdout重定向到您自己的文件等。

This example显示将其中一个标准管道重定向到文件并将其还原到系统提供的文件。或者,可以使用File参数设置为例如调用文件I / O子程序。 Ada.Text_IO.Standard_Output并且应该按预期工作 - 输出到终端或您在命令行上管道stdout的任何内容。

如果您正在阅读和撰写的数据不是文本,则Direct_IO, Sequential_IO, Stream_IO等应提供类似的设施。

Timur的回答显示你可以直接读写这些管道;这个答案的方法允许您使用其他文件统一处理标准管道,以便您可以通过文件或管道使用相同的代码进行I / O.例如,如果提供了命令行文件名,请使用该文件,否则请将文件指向Standard_Output

如果您询问命令行cmd1|main|grep "hello"中发生了什么,是的,cmd1的输出位于名为stdout(在C中)或Standard_Output(Ada)的管道上通过(特定于Unix的管道命令)连接到你在Ada写的Standard_Input程序的main。反过来,它的Standard_Output被传送到grep的stdin,它会搜索“你好”。

如果您问如何打开和访问命名管道,我怀疑这是特定于操作系统的,可能是一个更难的问题。

(在这种情况下,this Stack Exchange Q&A可能有帮助)。