我正在使用std::ifstream::read
从管道(Linux)或类似管道的设备对象(Windows)中读取。但是,当没有更多数据时,read
读取0个字节并设置EOF
。有没有办法从ifstream
进行阻塞读取,这样只有在有更多数据时它才会返回?
我宁愿不忙等待EOF
标志清除。
如果C ++标准库无法实现,那么最接近的其他选项是什么?我可以在纯C中执行此操作,还是必须使用特定于操作系统的API?
答案 0 :(得分:3)
不幸的是,std
在任何非算法功能上都很差,比如IO。您始终必须依赖第三方解决方案。幸运的是,有Boost,如果你不介意的话,我会建议用它来减少OS特定的代码。
namespace bs = boost::iostreams;
int fd; // Create, for example, Posix file descriptor and specify necessary flags for it.
bs::file_descriptor_source fds(fd);
bs::stream<bs::file_descriptor_source> stream(fds);
// Work with the stream as it is std stream
在这个小例子中,我使用Boost IO Streams,特别是file_descriptor_source
作为底层流设备,并在其中隐藏Windows或Posix特定管道。您自己打开的管道,因此您可以根据需要配置管道。
答案 1 :(得分:0)
好吧似乎无法进行阻止读取。清除错误位无济于事。只有在这个例子中重新打开fifo:
int main(int argc, char **argv)
{
int rc=0;
enum FATAL {ERR_ARGV,ERR_OPEN_FILE};
try
{
if( argv[1] == NULL) throw ERR_ARGV;
std::ifstream fifo;
while(1)
{
fifo.open(argv[1],std::ifstream::in);
if( !fifo.is_open() ) throw ERR_OPEN_FILE;
std::string line;
while(std::getline(fifo,line))
{
std::cout << line << "\n"; fflush(stdout);
}
fifo.close();
}
// never should come here
}
catch(FATAL e)
{
rc=e;
switch(e)
{
case ERR_ARGV:
std::cerr << "ERROR: argument 1 should be a fifo file name\n";
break;
case ERR_OPEN_FILE:
std::cerr << "ERROR: unabel to open file " << argv[1] << "\n";
break;
}
}
return(rc);
}
我测试了这段代码,它可以从fifo中无休止地读取。