использование QTextStream для чтения stdin неблокирующим способом

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

QSocketNotifier *pNot = new QSocketNotifier(STDIN_FILENO, QSocketNotifier::Read, this);
connect(pNot, SIGNAL(activated(int)), this, SLOT(onData()));
pNot->setEnabled(true);

на onData() слот выглядит так:

void CIPCListener::onData()
{
    qDebug() << Q_FUNC_INFO;
    QTextStream stream(stdin, QIODevice::ReadOnly);

    QString str;

    forever
    {
        fd_set stdinfd;
        FD_ZERO( &stdinfd );
        FD_SET( STDIN_FILENO, &stdinfd );
        struct timeval tv;
        tv.tv_sec = 0;
        tv.tv_usec = 0;
        int ready = select( 1, &stdinfd, NULL, NULL, &tv );
        if( ready > 0 )
        {
            str += stream.readLine();
        }
        else
        {
            break;
        }
    }

    qDebug() << "Recieved data:" << str;
}

как вы можете видеть, я пытаюсь использовать системный вызов select (), чтобы сообщить мне, когда у меня закончились данные для чтения. Однако на практике происходит вызов select () возвращает 0 после прочтения первой строки текста. Так, например, если я пишу 5 строк текста в поток stdin процесса, я только когда-либо читал первую строку.

в чем может быть проблема?

2 ответов


буфферизацию.

по умолчанию промывка после "\n". Если вы пишете 5 строк в свой процесс, ваш слот вызывается 5 раз. Если вы хотите избежать этого, вам нужно позвонить setbuf (stdin, _IOFBF). Но даже тогда не гарантируется, что вы можете читать произвольно большие объемы данных в одном куске.

Edit: вероятно, лучше использовать QTextStream:: atEnd() вместо select, так как QTextStream имеет свои собственные внутренние буферы.


Я нашел и пример в другом ответе, который подходит почти к этому вопросу и с полным и простым кодом:

https://stackoverflow.com/a/7389622/721929

Я использовал его для реализации приложения на основе консоли QT с текстовым меню для выбора пользователя.