D 编程 - 如何从 stdin 获取管道内容

D Programming - How to get the piped content from stdin

我想获取 D 程序标准输入中的管道内容,前提是它存在。

考虑以下因素

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

如果您通过管道传输内容,这会非常有效 例如

echo "poop" | test.exe

将打印出"poop"并继续执行。

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

我想评估内容已通过管道输入的事实,以便在没有管道内容时我不会执行 readline()。

有什么线索吗?谢谢!

有两种方法可以做到这一点:询问 stdin 上的数据是否可用并超时,或者查看 stdin 是管道还是用户交互控制台。这两者都是特定于平台的; D std 库不包含检查它们的函数。既然你说的是exe,那我就回答Windows。 (如果你不在 Windows,你想要的 posix 函数可能是 selectisatty,在网上搜索有关它们的信息。你也可以设置文件到非阻塞模式并尝试读取。)

要检查数据是否可用,您可以调用WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 50)。第二个参数是以毫秒为单位的超时 - 50 将足够快,以至于它对用户来说基本上是即时的,同时让程序有时间将内容传递给它。如果对象准备就绪,它将 return 归零;如果有可用的数据。

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 中完成。

另请参阅我对文件结尾问题的评论。