为啥我在使用 ifstream 通过命名管道读取一行后得到 EOF?
Posted
技术标签:
【中文标题】为啥我在使用 ifstream 通过命名管道读取一行后得到 EOF?【英文标题】:Why do I get EOF after reading one line thourgh a named pipe using ifstream?为什么我在使用 ifstream 通过命名管道读取一行后得到 EOF? 【发布时间】:2015-03-30 20:35:29 【问题描述】:在命令行中,我使用 mkfifo 创建了一个管道并确认该文件存在。 ls -al
给:
prw-r--r-- 1 user group 0 Mar 30 11:52 my_pipe
然后我使用此代码尝试从该管道中逐行读取文本:
ifstream pipe("/path/to/my_pipe");
string message;
while(getline(pipe, message) && message != "EXIT")
cout << boolalpha << pipe.good() << endl << pipe.eof() << endl << pipe.bad() << endl;
cout << boolalpha << pipe.good() << endl << pipe.eof() << endl << pipe.bad() << endl;
回到命令行我做echo "banana" > my_pipe
然后程序存在,输出如下:
true
false
false
false
true
false
这表明在读取banana
后流处于良好状态,但在第二次调用getline
时我点击EOF
并退出。
为什么我点击了EOF
,在我阅读我的特殊EXIT
消息之前,我可以做些什么来保持流的阅读并处于良好状态?
编辑:
结论:
-
使用
fstream
而不是ifstream
。
在撰写本文时,libc++ 中显然存在一个关于 fstream 和管道的错误。
【问题讨论】:
【参考方案1】:当管道被所有打开它以进行写入的进程关闭时,EOF 发生在管道上。在您的示例中,打开它进行写入的唯一进程是 echo
命令;当它退出时,它会关闭管道,导致读取过程中出现EOF。
如果您希望管道在每个写入它的客户端之间保持打开状态,那么方法就是以读写模式打开管道。这样,读过程也是写过程,只要管道打开,就不会被所有的写者关闭。
fstream pipe("/path/to/my_pipe");
或者,您可以通过在单个重定向进程中执行多个命令来保持发送端的管道打开:
( echo banana ; echo EXIT ) > my_pipe
【讨论】:
我尝试了一个普通的fstream
,但它永远不会从getline
返回。顺便说一句,ios::in|ios::out
是fstream
的默认模式,所以这有点多余。
只要有人写了一行,它就会从getline
返回。在那之前,它应该等待。不过,它永远不会离开循环。
我添加了一个答案,显示如何在 echo 命令之间保持管道打开。
是的,它“应该”从getline
返回,但它只是没有。适合你吗?这是我的实现中的错误吗?另外,我希望这个程序能够长期存在,而不仅仅是一次性收听一些回声的字符串。
我刚刚测试过了。我在一个窗口中启动程序,然后转到另一个窗口并执行echo foo > my_pipe
。第一个窗口打印true false false
。以上是关于为啥我在使用 ifstream 通过命名管道读取一行后得到 EOF?的主要内容,如果未能解决你的问题,请参考以下文章