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

时间:2011-11-15 13:05:21

标签: c linux file-io

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

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

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

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

编辑:要求正在等待使用“读取”,直到到达指定的字节。

2 个答案:

答案 0 :(得分: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]);

请注意,这将阻止您的程序,直到读取所有数据。读取的字符数可能少于所有内容,因为可能存在错误或用户按下了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);

有关tcsetattr功能和ICANON标志的详细信息,请查看tcsetattr的手册页。

答案 1 :(得分:0)

do {ioctl(fd_port, FIONREAD, &bytes);} while (bytes < size);

在发出read()之前可能会有所帮助。