阻止读取直到到达指定的数字字节

Lun*_*oms 1 c linux file-io

我需要等待使用"read",直到音频编解码器设备上的缓冲区已满.为了更容易,让我们采取类似的例子:

 fd= read(fileno(stdin), &buf, 10);
Run Code Online (Sandbox Code Playgroud)

当我在stdin中键入10个字符时,如何从读取返回?(我希望如果成功,我可以等待编解码器,直到达到指定的数据字节).

以上示例需要来自控制台的"输入密钥",其中我希望"读取"仅在到达所需的数据字节时解锁.

编辑:要求正在等待使用单个 "读取",直到到达指定的字节.

Som*_*ude 9

这个怎么样:

#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]);
Run Code Online (Sandbox Code Playgroud)

请注意,这将阻止您的程序,直到读取所有数据.读取的字符数可能少于所有内容,因为可能存在错误或用户按下CTRL-D(文件结尾).

另请注意,STDIN_FILE文件描述符很可能连接到tty,这意味着它可能是缓冲的,因此在换行之前不会返回数据,并且您可能必须使tty无缓冲.

编辑 要确保连接到stdin的tty是无缓冲的,请使用以下代码:

#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);
Run Code Online (Sandbox Code Playgroud)

有关tcsetattr函数和ICANON标志的更多信息,请查看手册页tcsetattr.