【问题标题】:read from a pipe: How to handle the return values in c?从管道中读取:如何处理 c 中的返回值?
【发布时间】:2016-05-26 08:24:23
【问题描述】:

我正在编写一个从管道读取的程序,我想知道处理返回值的正确方法是什么。根据阅读手册页,

成功时,返回读取的字节数(零表示文件结束),文件位置提前该数字。如果此数字小于请求的字节数,则不是错误;这可能会发生,例如因为现在实际可用的字节较少(可能是因为我们接近文件结尾,或者因为我们正在从管道或终端读取),或者因为 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() 不能读取超过指定大小的数据。如果我错了,请纠正我。

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

【问题讨论】:

  • 请发布一个工作示例。您的代码将无法编译。检查if((ret= pipefd 行。
  • 你对部分read-s的担心是对的;你绝对应该缓冲和处理这些

标签: c pipe return-value


【解决方案1】:

当您read 请求给定数量的数据时,但没有什么可以保证您可以读取与请求一样多的可用数据。例如,您可能会遇到文件结尾,或者编写器部分没有在您的管道中写入太多数据。所以read 返回你有效读取的内容,也就是返回读取的字节数(零表示文件结束)

如果read 返回一个严格的正数,那就清楚了。

如果read 返回 0,则表示文件结束。对于常规文件,这意味着您当前位于文件末尾。对于管道,这意味着管道是空的并且不会写入任何单个字节。对于管道,这意味着您已经读取了所有数据并且另一端不再有写入器(因此不会再写入字节),因此您可以关闭现在无用的管道。

如果read 返回-1,则表示发生了错误,您必须查阅errno 变量以确定故障原因。

因此,一般架构可能类似于:

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)
}

【讨论】:

    【解决方案2】:

    如果 read 返回 0,那么您的进程已经读取了来自该文件描述符的所有数据。将其从 read_fd 中取出,如果是 maxfd,则将 maxfd 重置为最新的最大值。根据您的流程正在做什么,您可能还需要进行其他清理工作。如果你得到一个简短的阅读,那么要么处理你收到的数据,要么丢弃它,或者存储它,直到你得到所有数据并可以处理它。

    很难对一个非常笼统的问题给出更具体的答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      相关资源
      最近更新 更多