是否可以使用重定向到stdin通过命名管道读取间歇发送的数据?

时间:2012-06-21 19:10:00

标签: c++ linux redirect named-pipes

是否可以使用重定向到stdin来通过命名管道读取间歇发送的数据?

我想做的是:

$ mkfifo pipe
$ ./test < pipe

在另一个终端:

$ cat datafile > pipe
$ cat datafile > pipe

将重复信息转储到管道中。这只是第一次有效。

这是一个显示行为的测试演示程序:

int main(int argc, char *argv[]) {  
    char input_string[30];
    while(1) {
        while( cin.read(input_string, 30) || cin.gcount()!=0 ) {
            cout << "!" << endl;
        }
    }
return 1;
}

那么,发生了什么?重定向是否仅提供单个发送到管道的内容?我已经编写了一个实际生产代码的版本,它将管道名称作为参数,并保持打开以便以这种方式编写,也许这就是答案。但我想知道是否有办法通过重定向来实现这一目标。

2 个答案:

答案 0 :(得分:1)

当您从管道重定向输入时,如下所示:

./test < pipe

shell打开管道进行读取,然后启动程序。但是在编写器存在之前打开管道才会完成 - 即open(2)阻塞。当另一个进程打开管道进行写入时,原始open调用完成,两者可以进行通信。当作者关闭管道的末端时,读取端也会关闭 - 读者得到一个EOF。

一旦完成该循环,您可以重新打开管道进行读取并开始另一个循环,但您必须自己完成。因此,如果您正在阅读stdin,则必须重新启动程序。或者,您可以在另一个文件描述符上重新打开管道,例如:

// Error checking omitted for expository purposes
int main(int argc, char **argv)
{
    while(1)
    {
        int fd = open("pipe", O_RDONLY);
        char buffer[30];
        int n;
        while((n = read(fd, buffer, sizeof(buffer)) > 0)
        {
            // Process input
        }
        close(fd);
    }

    return 0;
}

如果要将原始I / O包装在stdio FILE*中,可以使用fdopen(3);我不知道如何将文件描述符包装在C ++流对象中,尽管它可能是可能的。

答案 1 :(得分:0)

$ cat datafile > pipe

将数据文件的内容发送到管道,并发送EOF(文件末尾)。此时重定向已关闭,之后推送到管道的数据不再重定向到./test