Read input from a pipe in Ada

China☆狼群 提交于 2019-12-25 18:35:36

问题


I have a piece of code (see below) that reads data from a file given as a command line argument. I would like to add a support for being able to read the input from a pipe. For instance, the current version reads the data as main <file_name>, whereas it should also be possible to do something line cmd1 | main. Here is the source to read data from file:

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;

If I understood correctly, a pipe is just a non-regular file type in Ada. But how do I deal with it?


回答1:


None of these seem to really answer your question. A pipe merely makes the standard output of another program be the standard input of your program, so you read a pipe by reading Standard_Input.

The function Current_Input returns a File_Type. It initially returns Standard_Input, but calling Set_Input changes it to return whatever you passed to Set_Input. So a rough outline of how to read from Standard_Input if no file is given, and from the given file if one is, looks like:

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:


You don't even need to create a file to be able to read data from pipe.

just

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;

And after that type ..\src\main.adb | main.exe works.




回答3:


Quoting from the ARM...

The library package Text_IO has the following declaration:

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

which allow you to manipulate the default pipes stdin, stdout, stderr as files; either as pre-opened files (input and output pipes) or allow you to redirect stdout to your own file, etc.

This example shows redirecting one of the standard pipes to a file and restoring it to the system provided file. Alternatively, File I/O subprograms may be called with the File argument set to e.g. Ada.Text_IO.Standard_Output and should simply work as expected - outputting to Terminal or to whatever you piped stdout to on the commandline.

Similar facilities should be available in Direct_IO, Sequential_IO, Stream_IO etc if the data you're reading and writing isn't text.

Timur's answer shows you can read and write directly to these pipes; this answer's approach allows you to treat the standard pipes uniformly with other files, so that you can I/O either via file or pipe with the same code. For example, if a commandline filename is supplied, use that file, otherwise point your File at Standard_Output.

And if you're asking what happens in the command line cmd1|main|grep "hello", yes, the output of cmd1 is on a pipe called stdout (in C) or Standard_Output (Ada) which is connected via the (Unix-specific pipe command) | to the Standard_Input of your main program written in Ada. In turn, its Standard_Output is piped into grep's stdin which it searches for "hello".

If you are asking how you open and access named pipes, I suspect that is OS specific, and may be a more difficult question.

(In which case, this Stack Exchange Q&A may help).



来源:https://stackoverflow.com/questions/48187514/read-input-from-a-pipe-in-ada

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!