Блокировка считывается до тех пор, пока не поступит указанное количество байт - PullRequest
1 голос
/ 15 ноября 2011

У меня есть требование подождать, используя «чтение», пока на устройстве с аудиокодеком не будет заполнен буфер.Для простоты, давайте возьмем похожий пример:

 fd= read(fileno(stdin), &buf, 10);

Как я могу вернуться из чтения, когда я набираю 10 символов в stdin?(Я надеюсь, что в случае успеха, я могу подождать на кодеке, пока не прибудут указанные байты данных.)

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

РЕДАКТИРОВАТЬ: Требование ожидает, используя однократное «чтение», пока не будут получены указанные байты.

Ответы [ 2 ]

9 голосов
/ 15 ноября 2011

Как насчет этого:

#define BUFFER_SIZE 10
char buffer[BUFFER_SIZE];

/* ... */

size_t total_read = 0;
size_t total_left = BUFFER_SIZE;  /* The total size of the buffer */
char *buffer_pointer = buffer;    /* buffer is where to store the data */
while (total_left > 0)
{
    ssize_t current = read(STDIN_FILENO, buffer_pointer, total_left);
    if (current <= 0)
    {
        /* Error or end of file */
        if (current < 0)
            perror("read");  /* Error! */
        break;
    }
    else
    {
        total_read += current;     /* We have read some more data */
        total_left -= current;     /* Less data left to read */
        buffer_pointer += current; /* So we don't read over already read data */
    }
}

printf("Received %ld characters\n", total_read);
for (unsigned int i = 0; i < total_read; i++)
    printf("Character #%d: '%c'\n", i, buffer[i]);

Помните, что это заблокирует вашу программу, пока все данные не будут прочитаны.Количество прочитанных символов может быть меньше всего, потому что может быть ошибка или пользователь нажал CTRL-D (конец файла).

Также обратите внимание, что дескриптор файла STDIN_FILE, скорее всего, подключен кtty, что означает, что он может быть буферизован, поэтому не возвращает данные до новой строки, и вам, возможно, придется отключить буферизацию tty.

Edit Чтобы убедиться, что tty подключен к stdinнебуферизованный, используйте следующий код:

#include <termios.h>

/* ... */

/* Somewhere before reading from stdin... */
struct termios tty_settings;

tcgetattr(STDIN_FILENO, &tty_settings);
tty_settings.c_lflag &= ~ICANON;
tcsetattr(STDIN_FILENO, TCSANOW, &tty_settings);

Для получения дополнительной информации о функции tcsetattr и флаге ICANON проверьте страницу справочника для tcsetattr.

0 голосов
/ 13 марта 2014
do {ioctl(fd_port, FIONREAD, &bytes);} while (bytes < size);

Может помочь, до выдачи read().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...