2010-10-05 160 views
6

如何从C++/Qt Linux应用程序中逐行读取FIFO /命名管道?如何从C++/Qt Linux应用程序中逐行读取FIFO /命名管道?

今天我可以打开并从一个Qt程序的前端读取, 但我不能让程序逐行读取数据。 Qt读取整个文件,这意味着他等待直到“发件人”关闭他的会话。

让我们以一些shell命令为例来展示我想要的应用程序。

首先创建一个FIFO

mkfifo MyPipe 

然后我们可以使用cat从FIFO

cat MyPipe 

然后我们与另一只猫发送一些数据读取

cat > MyPipe 

而且然后开始输入一些东西,每次你输入它就会到达读者。 然后当你用Ctrl + D关闭它时,双方都结束。

现在发件人很容易创建一个QTextStream, 你只需要刷新,当你想发送。

QFile file("MyPipe"); 
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) 
    return; 

QTextStream out(&file); 
for(int i=0; i<3; i++) { 
    out << "Hello...: " << i << "\n"; 
    out.flush(); 
    sleep(2); 
} 

file.close(); 

但随后写一个小读者通过读取线线是我现在很卡, 我所有的尝试与Qt的LIB与最终我得到的数据,但 直到发件人在fifo上使用file.close()。 不是当他冲洗时,就像我用猫读书时发生的那样。

像这个例子:

QFile file("MyPipe"); 
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) 
    return 0; 

QTextStream in(&file); 
QString line; 
do { 
    line = in.readLine(); 
    qDebug() << line; 
} while (!in.atEnd()); 


file.close(); 

我缺少什么?

它只是感觉就像我需要使用某种类型的isReady或lineAvailable对 流或类似的东西, 但我无法找到适合的文档什么...

/感谢


如果我去的低C级的风格,在我做 时读取一个字符获取其风格林海冲刺。 但能够做到相同的Qt风格会很好。

FILE *fp; 
fp=fopen("MyPipe", "r"); 
char c; 
while((c=getc(fp)) != EOF) 
{ 
    printf("%c",c); 
} 
fclose(fp); 

更新

当我开始调试程序挂在的readLine(), 不要继续下去,直到对方关闭FIFO。

和我做同样的使用得到“>>”

line = in.readLine(); 
    in >> line; 
+1

难道是管道正在被立即读取,它实际上是被缓冲的屏幕输出?你用过'qDebug()<< line;',我没有看到任何冲洗。 – 2010-10-30 20:54:20

+0

好点,没想到那个。 – Johan 2010-10-31 07:41:08

回答

4

使用低级c风格并读取一个字符。

FILE *fp; 
fp=fopen("MyPipe", "r"); 
char c; 
while((c=getc(fp)) != EOF) 
{ 
    printf("%c",c); 
} 
fclose(fp); 
+0

'c'必须是'int',否则它可能是一个无限循环如果'char'是无符号的('EOF'是负整数通常情况下为'-1') – jfs 2013-11-24 08:20:38

2

我不知道有什么不工作,但你可以尝试使用strace的调试它:

strace -o writer.log -e trace=write ./writer 
strace -o reader.log -e trace=read ./reader 

第一行将记录您的编写器程序所做的所有写入系统调用。第二行以类似的方式工作。 这样你可以跟踪系统调用,并确保你的冲洗工作。

如果你看到重复的调用读取,有正确的时间和数据,那么你有QTextStream的问题。

如果你不使用QTextStream,但直接从文件中读取会发生什么?

+0

strace很好,我在另一个窗口中开始了“watch tail reader.log”,我可以看到他确实获得了我发给他的数据。 – Johan 2010-10-05 11:19:24

+0

@Johan:你确定问题出在读者身上吗? – shodanex 2010-10-06 11:34:08

+0

95%肯定,因为如果我用“C版本”替换它的工作,“Qt版本”。 – Johan 2010-10-06 12:34:51

1

您可以尝试用QIODevice::Unbuffered标志打开阅读器端的文件。

+1

上帝的主意,但它仍然是一样的:( – Johan 2010-10-05 17:05:24

2
if(file.bytesAvailable()) 
QString line = file.readLine(); 

你可以使用这样的事情。

+0

对于特殊文件(包括命名管道),QFile实现的bytesAvailable不起作用,事实上使应用程序崩溃! – 2016-06-09 13:20:09