D编程 - 如何从标准输入获取管道内容

时间:2015-02-19 12:28:54

标签: pipe d stdin readline readlines

我想在D程序的stdin中获取管道内容,只要它在那里。

考虑以下

string output;
char[] buf;
while (stdin.readln(buf))
{
    output ~= buf;
}
return output;

如果您管道内容,这非常有用 例如

echo "poop" | test.exe

将打印出“大便”并继续执行。

但是,如果你只是运行test.exe,它将在那里等待CTRL + C然后继续。

我想评估内容已被管道输入的事实,这样如果没有管道内容,我就不会使用readline()。

任何线索?谢谢!

1 个答案:

答案 0 :(得分:4)

有两种方法可以执行此操作:询问stdin上的数据是否可用超时,或者查看stdin是管道还是用户交互式控制台。这两者都是特定于平台的; D std库不包含检查它们的功能。既然你正在谈论exe,我将给出Windows的答案。 (如果你不在Windows上,你想要的posix函数可能是selectisatty,在网上搜索有关它们的信息。你也可以将文件设置为非阻塞模式并尝试读出。)

要检查数据是否可用,您可以致电WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 50)。第二个参数是以毫秒为单位的超时 - 50会足够快,以至于它对用户来说基本上是即时的,同时给程序时间管道内容。如果对象准备好,它将返回零;如果有数据可用。

https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032%28v=vs.85%29.aspx

WaitForSingleObjectSTD_INPUT_HANDLE都是在D中定义的import core.sys.windows.windows;

import core.sys.windows.windows;
import std.stdio;

void main() {
        if(WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 50) == 0) {
                string output;
                char[] buf;
                while (stdin.readln(buf))
                {
                    output ~= buf;
                }
                writeln(output);
        }
}

判断stdin是否是一个控制台....好吧,说实话,我不记得如何在Win32中做到这一点并且需要立即行动!也许我今晚可以回来编辑它,但是如果你能找到一个C解决方案,同样的事情也可以在D中完成。

另见我对文件结尾问题的评论。