Как читать FIFO / named pipe line by line из приложения C++/Qt Linux?

как читать FIFO / именованный трубопровод по строкам из приложения C++/Qt Linux?

сегодня я могу открыть и прочитать из fifo из программы Qt, но я не могу заставить программу читать данные строка за строкой. Qt читает весь файл, то есть он ждет, пока "отправитель" не закроет свой сеанс.

давайте возьмем пример с некоторыми командами оболочки, чтобы показать, что я хотел бы сделать приложение.

сначала создайте fifo

mkfifo MyPipe

тогда мы можем использовать cat для чтения из ФИФО

cat MyPipe 

и затем мы отправляем некоторые данные с другим котом

cat > MyPipe

а затем начните вводить что-то, и каждый раз, когда вы нажмете enter, он прибывает в читатель. И затем, когда вы закрываете его с помощью 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 заканчиваются тем, что я получаю данные, но пока отправитель не использует файл.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 или на печать л ручей или что-то в этом роде., но я не могу найти ничего в документах, что припадки...

/спасибо


Примечание:

если я иду со стилем низкого уровня c и читаю один символ в то время, когда я это делаю получите стиль, который я ищу. Но было бы неплохо иметь возможность делать тот же стиль Qt.

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

обновление:

когда я запускаю отладчик, программа висит на строке чтения(), и не продолжайте, пока другая сторона не закроет fifo.

и я получаю то же самое с помощью ">>"

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

4 ответов


используйте стиль низкого уровня c и прочитайте один символ в то время.

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

Я не знаю, что не работает, но вы можете попробовать отладить его с помощью strace:

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

первая строка будет регистрировать все системные вызовы записи, сделанные вашей программой записи. Вторая линия работает аналогичным образом. Таким образом, вы можете отследить системный вызов и убедиться, что ваш промывка работает.

Если вы видите повторный вызов для чтения, с правильным временем и данными, то у вас есть проблема с QTextStream.

что произойдет, если вы не используете QTextStream, но непосредственно читать из файла ?


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

вы можете использовать что-то вроде этого.


вы можете попробовать открыть файл на стороне читателя с помощью QIODevice::Unbuffered флаг.