从 Ada 中的管道读取输入
Read input from a pipe in 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 中的一种非常规文件类型。但是我该如何处理呢?
您甚至不需要创建文件就可以从管道读取数据。
就
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
有效。
引用自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;
允许您将默认管道 stdin, stdout, stderr
作为文件进行操作;作为预先打开的文件(输入和输出管道)或允许您将标准输出重定向到您自己的文件等。
This example 显示将标准管道之一重定向到文件并将其恢复到系统提供的文件。或者,可以调用 File I/O 子程序,并将 File 参数设置为例如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 编写的 main
程序的 Standard_Input
。反过来,它的 Standard_Output
被输送到它搜索 "hello".
的 grep 的 stdin
如果您问的是如何打开和访问命名管道,我怀疑这是 OS 特定的,并且可能是一个更难的问题。
(在这种情况下,this Stack Exchange Q&A 可能会有所帮助)。
None 这些似乎真正回答了您的问题。管道只是将另一个程序的标准输出作为您程序的标准输入,因此您可以通过读取 Standard_Input.
来读取管道。
函数 Current_Input return 是 File_Type。它最初是 returns Standard_Input,但是调用 Set_Input 将它更改为 return 无论您传递给 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;
我有一段代码(见下文)从作为命令行参数给出的文件中读取数据。我想添加对能够从管道读取输入的支持。例如,当前版本读取数据为 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 中的一种非常规文件类型。但是我该如何处理呢?
您甚至不需要创建文件就可以从管道读取数据。
就
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
有效。
引用自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;
允许您将默认管道 stdin, stdout, stderr
作为文件进行操作;作为预先打开的文件(输入和输出管道)或允许您将标准输出重定向到您自己的文件等。
This example 显示将标准管道之一重定向到文件并将其恢复到系统提供的文件。或者,可以调用 File I/O 子程序,并将 File 参数设置为例如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 编写的 main
程序的 Standard_Input
。反过来,它的 Standard_Output
被输送到它搜索 "hello".
stdin
如果您问的是如何打开和访问命名管道,我怀疑这是 OS 特定的,并且可能是一个更难的问题。
(在这种情况下,this Stack Exchange Q&A 可能会有所帮助)。
None 这些似乎真正回答了您的问题。管道只是将另一个程序的标准输出作为您程序的标准输入,因此您可以通过读取 Standard_Input.
来读取管道。函数 Current_Input return 是 File_Type。它最初是 returns Standard_Input,但是调用 Set_Input 将它更改为 return 无论您传递给 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;