如何从 C++/Qt Linux 应用程序中逐行读取 FIFO/命名管道?
如何从 C++/Qt Linux 应用程序中逐行读取 FIFO/命名管道?
今天我可以从 Qt 程序中打开并读取 fifo, 但我无法让程序逐行读取数据。 Qt 读取整个文件,这意味着他会等到“发送者”关闭他的会话。
让我们以一些 shell 命令为例来展示我希望应用程序执行的操作。
首先创建一个fifo
mkfifo MyPipe
然后我们可以使用cat从fifo中读取
cat MyPipe
然后我们用另一只cat发送一些数据
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 库的所有尝试最终都得到了数据,但是 直到发送方在 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;
How do I read a FIFO/named pipe line by line from a C++/Qt Linux app?
Today I can open and read from a fifo from a Qt program,
but I can't get the program to read the data line by line.
Qt reads the entire file, meaning he waits until the "sender" closes his session.
Let's take a example with some shell commands to show what I would like the app to do.
First create a fifo
mkfifo MyPipe
Then we can use cat to read from the fifo
cat MyPipe
And then we send some data in with another cat
cat > MyPipe
And then start to type something, and every time you hit enter it arrives at the reader.
And then when you close it with Ctrl+D both sides end.
Now the sender is easy to create with a QTextStream,
you just need to flush when you want to send.
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();
But then to write a little reader that read line by line is where I'm stuck right now,
all my tries with the Qt lib ends up with that I get the data but
not until the sender uses file.close() on the fifo.
Not when he flush, as occurs when I use cat to read.
Like this example:
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();
What am I missing?
It just feels like I need to use some kind of isReady or lineAvailable on
the stream or something like that,
but I can't find anything in the docs that fits...
/Thanks
Note:
If I go with the low level c style and read one char at the time I do
get the style Im searching for.
But it would be nice to be able to do the same Qt style.
FILE *fp;
fp=fopen("MyPipe", "r");
char c;
while((c=getc(fp)) != EOF)
{
printf("%c",c);
}
fclose(fp);
Update:
When I start a debugger the program is hanging on the readLine(),
and do not continue until the other party closes the fifo.
And I do get the same using ">>"
line = in.readLine();
in >> line;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
使用低级c风格并一次读取一个字符。
Use the low level c style and read one char at the time.
我不知道什么不起作用,但您可以尝试使用 strace 对其进行调试:
第一行将记录您的编写程序进行的所有写入系统调用。第二行以类似的方式工作。
这样你就可以跟踪系统调用,并确保你的刷新工作正常。
如果您看到重复调用 read 且时间和数据正确,则 QTextStream 存在问题。
如果您不使用 QTextStream,而是直接从文件中读取会发生什么?
I don't know what does not work but you can try to debug it using strace:
The first line will log all the write system call made by your writer program. The second line works in a similar fashion.
This way you can trace the system call, and be sure that your flushing works.
If you see repeated call to read, with the correct timing and data, then you have a problem with QTextStream.
What happens if you don't use a QTextStream, but directly read from the file ?
你可以使用这样的东西。
You could use something like this.
您可以尝试使用
QIODevice::Unbuffered
标志在读取器端打开文件。You could try to open the file on the reader side with the
QIODevice::Unbuffered
flag.