Unix系统中的文件读取()函数

如果由于信号中断而导致read()函数失败,则重新启动read()函数。 read()从它被中断的地方恢复读取。 所以如果read()在读取EOF字符之前被中断,它将返回多less字节它读取?

 int r_read(int fd, void *buf, int size) { while((retval=read(fd,buf,size))==-1 && errno ==EINTR); return retval; } 

问候。

这就是为什么读取的字节数应该保持为总数,以避免中断问题。 这对于非阻塞I / O也很有用。

 { int ret = 0, nread; char *nbuf = (char *) buf; while ((nread = read(fd, nbuf, size)) != 0) { if (nread > 0) ret += nread, nbuf += nread, size -= nread; elif (errno != EINTR) break; } return ret; } 

如果errno == EINTR ,则意味着在根据man页可以读取任何数据之前, read被中断。 也就是说,从我的阅读中,就像在流中的数据一样, EINTR状态的read就没有发生。 所以好像你可以简单地重试而不用担心丢失了任何字节。 我觉得这有点令人惊讶,而且我还没有真正测试过,但手册中提到这一点。

以下是手册页中的实际文本:

EINTR在读取数据之前,呼叫被信号中断; 见信号(7)。

编辑:我现在测试了这一点,我发现,如果我打断了读, EINTR只会返回,如果阅读被中断之前已经读取任何东西。 否则,它将成功返回,读取的字节数小于所请求的数量。 所以为了得到你想要的字节数,你将需要重新启动一些东西,正如另一个答案所表明的那样。

这里没有“EOF字符”,表示为0字节的读取结束的文件结束条件。 EINTR错误只有在等待事件发生时才中断read ,即底层资源产生任何数据之前。

由于EOF通常会导致read停止等待并返回一个值,因此read操作不能被中断,如果这样做,它只会返回它所具有的EOF指示符。 如果read等待 EOF(在被底层资源公布之前)中断,它当然会返回-1并设置EINTR。