2016-02-15 39 views
1

我正在编写一个程序来读取管道,我想知道处理返回值的正确方法是什么。根据所读取的手册页,从管道读取:如何处理c中的返回值?

成功时返回读取的字节数(零表示文件结束),并且文件位置按该数字提前。如果此数字小于请求的字节数,则不是错误;这可能会发生,例如因为现在实际上可用的字节更少(可能因为我们接近文件结束,或者因为我们正在从管道读取数据或从终端读取数据),或者因为read()被中断信号。

我很担心它只能读取一半数据的情况。另外,当返回值为零时,处理这种情况的正确方法是什么?

这是我的示例代码。

struct day 
{ 
     int date; 
     int month; 
}; 

while(1) 
{ 
     ret = select(maxfd+1, &read_fd, NULL, &exc_fd,NULL); 
     if(ret < 0) 
     { 
       perror("select"); 
       continue; 
     } 
     if(FD_ISSET(pipefd[0], &read_fd)) 
     { 
       struct day new_data; 
       if((ret = read(pipefd[0], &new_data, sizeof(struct day)))!= sizeof(struct day)) 
       { 
         if(ret < 0) 
         { 
           perror("read from pipe"); 
           continue; 
         } 
         else if(ret == 0) 
         { 
           /*how to handle?*/ 
         } 
         else 
         /* truncated read. How to handle?*/ 
       } 
     } 
     ... 
} 

我相信read()不能读取比指定大小更多的数据。如果我错了,请纠正我。

请帮我处理读取的返回值。

+0

请张贴工作的例子。你的代码不会编译。检查'if((ret = pipefd' line。 – ceving

+0

你是对的,担心部分'read' -s;你肯定应该缓冲并处理这些 –

回答

0

当您请求给定数量的数据时,但没有任何东西可以保证您有足够的可用数据来读取您请求的数据。例如,您可能会遇到文件结尾,或者写入程序部分没有在管道中写入太多数据。所以read返回你有效读取的内容,即返回的字节数(0表示文件结尾)

如果read返回严格正数,则很明显。

如果read返回0,则表示文件结束。对于一个常规文件,这意味着你目前在文件的末尾。对于一个管道来说,这意味着管道是空的不会写入单个字节。对于管道来说,这意味着您已经读取了所有数据,并且另一端没有更多的写入器(这样就不会再写入更多的字节),因此您可以关闭现在无用的管道。这意味着错误发生了,你必须咨询errno变量,以确定故障的原因

如果read返回-1。

所以,一般的模式可能是这样的:

n = read(descriptor,buffer,size); 
if (n==0) { // EOF 
    close(descriptor); 
} else if (n==-1) { // error 
    switch(errno) { // consult documentations for possible errors 
    case EAGAIN: // blahblah 
    } 
} else { // available data 
    // exploit data from buffer[0] to buffer[n-1] (included) 
} 
0

如果读取返回0,那么您的进程已经读取了来自该文件描述符的所有数据。把它从read_fd中取出,如果它是maxfd reset maxfd到最新的最大值。根据你的过程在做什么,你也可以做其他的清理工作。如果你读了一段短文,那么要么处理你收到的数据,要么丢弃它,要么存储它,直到你获得所有的数据并且可以处理它。

很难给出一个非常普遍的问题的更具体的答案。