Как читать 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();
вы можете использовать что-то вроде этого.