read()函数的困惑

#define BUF_SIZE 10

int main()
{
        int cnt;
        char buf[BUF_SIZE];
        cnt = read(STDIN_FILENO, buf, BUF_SIZE);
        printf("cnt = %d\n", cnt);
        return 0;
}

给定代码如上所示。编译后运行。

./a.out 
abc
cnt = 4

abc 是输入的数据,加上换行符,因此是4个字符,cnt=4。

但是此时如果我们使用重定向,采用文件作为输入,文件中包含两行的内容。我们会发现read()函数不会在读到换行符后就停止,而是直接读完整个文件。

//inside input_file. This line is not in the file.
123
456

得到

./a.out < input_file
cnt = 8

可以看到,read()函数对于不同的输入来源有着不同的行为。我在此处找到了相应的解释。下面是搬运。链接种还说明了一些较为不常见的情况,下面只搬运了较常用的情形:

read()函数对于不同的输入会有不同的表现。对于一般的文件输入,如果要求读入N个字符,那么在有N个字符可供读入的情况下,read()会读入N个字符,如果已经读到文件尾也即EOF,小于N的个数的字符会被读取。

如果read()是从一个标准的终端读入数据,那么tty驱动器会以一次一行的形式向read()提供输入。因此如果你令read()读入3个还是300个字符,read()都会被挂起,直到tty遇到一个换行符,或者遇到EOF后将数据提供给read()。而read()在读取数据后则会将实际读取的字符个数返回,该个数为请求读入的字符个数或者可供读入数据的个数中的较小者。

若读取的文件描述符被设置成为非阻塞,那么read()在没有数据可供读取时将立即返回而不阻塞,返回值是-1,且errno会被设为EAGAIN or EWOULDBLOCK,这种情况一般用于对套接字的读取。

因此在使用read()时需要小心,不一定请求读取多少数据就会读到多少数据,此外,还有可能会遇到如EINTR等非致命性错误,这个错误提示你需要重试read()

posted on 2017-03-14 16:00  caiminfeng  阅读(1502)  评论(0编辑  收藏  举报

导航