繁体   English   中英

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

[英]How do I read a FIFO/named pipe line by line from a C++/Qt Linux app?

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

今天我可以从Qt程序打开并读取fifo,但是我不能让程序逐行读取数据。 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;

使用低级c样式并在当时读取一个char。

FILE *fp;
fp=fopen("MyPipe", "r");
char c;
while((c=getc(fp)) != EOF)
{
    printf("%c",c);
}
fclose(fp);
if(file.bytesAvailable())
QString line = file.readLine();

你可以使用这样的东西。

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

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

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

如果您看到重复调用read,使用正确的时序和数据,那么QTextStream就会出现问题。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM