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;
Use the low level c style and read one char at the time.
FILE *fp;
fp=fopen("MyPipe", "r");
char c;
while((c=getc(fp)) != EOF)
{
printf("%c",c);
}
fclose(fp);