如何检查读取系统调用是否已读取整个数据

时间:2013-08-23 11:11:31

标签: c linux serial-port

我需要知道read系统调用是否已读取整个数据。如果缓冲区中没有数据,则默认情况下read系统调用块,但不能确保数据已完全读取。请告诉我一个正确的确认方法。

在手册页中,有人说read系统调用在遇到我尝试过的文件结尾时返回0,并且read没有返回0毕竟。

wr_cnt =write(fd, "AT+CGMI\r", sizeof("AT+CGMI\r"));

  if(wr_cnt<0)
        perror("Write to dev failed");
  else
       printf("No.of bytes written=%d\n",wr_cnt);

  while(1)
  {
      //rd_cnt =read(fd, &str, 1);
      if((rd_cnt =read(fd, &str, 1)) <=0)
    {
            perror("Read to dev failed");
            printf("error no=%d\n",errno);
            break;
    }

        printf("char =%c ->  hex=%x rd_cnt=%d\n",str,str,rd_cnt);
        sleep(3);
        str=0;
 }      

 if(rd_cnt==0)
    printf("EOF met\n");

1 个答案:

答案 0 :(得分:2)

默认情况下,read不会返回零,表示EOF,除非它确实是文件的末尾,或者连接已关闭。如果流连接仍处于打开状态,但现在恰好没有可用的数据,read只会“挂起”,直到某些内容到达。

有两种解决方案。

  1. 将文件描述符设置为非阻塞模式。如果没有数据,则read将返回-1errno将设置为EAGAINEWOULDBLOCK(您还应该检查EINTR无论如何,无论如何)。可能还有其他原因导致输入阻塞,因此您应该在短时间内重试以确保。

  2. 在阅读之前使用select 。它在代码中更加冗长,但在运行时更有效。 select仅在可以确定后续读取不会阻止或者达到超时时返回。您可以将超时解释为流式数据的“EOF”。如果您正在阅读来自多个流的输入,则select是绝对必须的。