Come si legge un FIFO/named pipe per linea da un'app C++/Qt Linux?Come si legge un FIFO/named pipe line by line da un'app C++/Qt Linux?
Oggi posso aprire e leggere da un fifo da un programma Qt, ma non riesco a ottenere il programma per leggere i dati riga per riga. Qt legge l'intero file, il che significa che aspetta che il "mittente" chiuda la sua sessione.
Facciamo un esempio con alcuni comandi della shell per mostrare cosa vorrei fare l'app.
Innanzitutto creare una FIFO
mkfifo MyPipe
Poi possiamo usare cat per leggere dal FIFO
cat MyPipe
E poi mandiamo alcuni dati con un altro gatto
cat > MyPipe
E quindi inizia a digitare qualcosa, e ogni volta che premi entri, arriva al lettore. E poi quando lo chiudi con Ctrl + D entrambi i lati finiscono.
Ora il mittente è facile da creare con QTextStream, , è sufficiente svuotare quando si desidera inviare.
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();
Ma poi di scrivere un piccolo lettore che leggere riga per riga è dove mi sono bloccato in questo momento, tutti i miei tentativi con la lib Qt finisce con che ottengo i dati, ma non fino il mittente usa file.close() sulla fifo. Non quando arrossisce, come succede quando uso cat per leggere.
come in questo esempio:
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();
Che cosa mi manca?
Si sente proprio come ho bisogno di utilizzare una sorta di isReady o lineAvailable sul torrente o qualcosa di simile, ma non riesco a trovare nulla nella documentazione che si adatta ...
/Grazie
Nota:
Se vado con il c stile a basso livello e letto un carattere al tempo che faccio otteniate Im mare stile cazzeggio per. Ma sarebbe bello poter fare lo stesso stile Qt.
FILE *fp;
fp=fopen("MyPipe", "r");
char c;
while((c=getc(fp)) != EOF)
{
printf("%c",c);
}
fclose(fp);
Aggiornamento:
Quando inizio un debugger il programma è appesa al readLine(), e non continuare fino a quando l'altra parte chiude il FIFO.
E io capisco lo stesso con ">>"
line = in.readLine();
in >> line;
Potrebbe essere che la pipe viene letta immediatamente, e in realtà è l'output dello schermo che viene bufferizzato? Hai usato 'qDebug() << line;' e non vedo alcun flushing. –
Buon punto, non ci ho pensato. – Johan