Linux系统调用 - read

read()系统调用的原型:ssize_t read(int fd, void *buf, size_t count);

功能:从指定的文件描述符中读取最多count个字节的数据到指定的buf中去。如果传入的count是0,这个系统调用什么都不干,直接返回0。如果指定的count大于0,而且返回值也大于0,则表示函数执行成功,返回值表示成功读取的字节数,同时被读取的文件的当前数据指针会相应后移。如果返回值为0,表示遇到了文件结尾。如果读取失败,read()会返回-1,并设置errno。

但是有时候,返回-1并不一定表示文件坏了读不了了,比如:

如果在套接字上设置了O_NONBLOCK属性(非阻塞),而当前套接字上又没有数据可读,那么read()系统调用就会返回EAGAIN或者EWOULDBLOCK,表示暂时读不到东西,稍后再来试吧。

再比如,虽然当前套接字是阻塞模式的,但是设置了发送或接收超时时间,那么read()就会阻塞在套接字上等待数据过来,如果在超时时间内没有拿到任何数据,那么也会收到一个EAGAIN或者EWOULDBLOCK的errno,这时也应该稍后再来重新尝试读取。

另外还要注意,POSIX标准中并没有规定在上面两种情况下应该把errno设置为EAGAIN还是EWOULDBLOCK,实现中设置这两个错误代码都是可以的,所以一个程序要具有更好的适用范围,应该总是把这两个errno放在一起检查。

除此之外,还有一个errno,叫EINTR,表示在读取过程中,在读到数据之前被信号打断了,这时也应该当做正常情况处理,信号处理程序执行完成之后,只要程序还能再回来,就应该当没事一样继续正常的逻辑,重新读一次。

其他一些错误代码就要表示读取失败了,如EBADF,EFAULT,EINVAL,EIO等,具体就请参见帮助手册吧。

用read()系统调用读取本地磁盘设备上的文件时,通常可以认为读取速度是足够快的,因此通常不会设置O_NONBLOCK标志。在有些系统的实现上,设置会让非阻塞标志在处理本地磁盘文件是不生效。

猜你喜欢

转载自blog.csdn.net/yubo112002/article/details/82984688