Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用read()函数时检查EOF_C_Named Pipes_Polling_File Descriptor - Fatal编程技术网

C 使用read()函数时检查EOF

C 使用read()函数时检查EOF,c,named-pipes,polling,file-descriptor,C,Named Pipes,Polling,File Descriptor,这是我第一次使用文件描述符进行读取,我已经通过反复试验进行了大约3个小时的测试,我的阅读器几乎可以正常工作了!我只需要一点帮助来检查命名管道上的EOF 好的,我打开一个(井倍数)命名管道,如下所示: fds[j].fd = open(pipeNameo, O_RDWR) ; // storing it into my file descriptor array 然后,我轮询指定的管道,以查看是否有任何内容通过(轮询在循环中): 当出现问题时,我通过将写入的文件描述符发送到此函数来处理文件: i

这是我第一次使用文件描述符进行读取,我已经通过反复试验进行了大约3个小时的测试,我的阅读器几乎可以正常工作了!我只需要一点帮助来检查命名管道上的EOF

好的,我打开一个(井倍数)命名管道,如下所示:

fds[j].fd = open(pipeNameo, O_RDWR) ; // storing it into my file descriptor array
然后,我轮询指定的管道,以查看是否有任何内容通过(轮询在循环中):

当出现问题时,我通过将写入的文件描述符发送到此函数来处理文件:

int processFileDes( int fd )
{
    char buf[10] ;

    read(fd, buf, 1) ;
    char curr = buf[0] ;
    while (curr != EOF)
    {

        if ( curr == ' ')
        {
            // do nothing it is a space
        }
        else if ( curr == '\n')
        {
            printf("NEW LINE!\n") ;
        }
        else
        {
            int num = curr - '0' ; // turns char number into an int
            printf("Curr Num: %d\n", num) ;
        }

        printf("BEFORE\n"); // Gets stuck here when EOF, this is the string of output
        read(fd, buf, 1) ;
        printf("AFTER\n") ;

        curr = buf[0] ;
    }
printf("Success!\n") ; // this is never printed
return 0 ;
}
除了在读取完所有字符后,
read()
函数被卡住(我想是在等待返回)之外,所有操作都非常正常。
EOF应该在哪里。我需要能够检查EOF

我尝试了一种解决方法,通过计算读取的字符数(因为我知道输入的大小)来停止程序的读取,它会起作用,唯一的问题是当最后一个字符后有一个空格时,它会导致循环轮询返回1,并在剩余的空格上再次运行
processFile()
(非有效输入)留待读取

请帮忙:')

输入只是一个数字矩阵,如下所示:

0 1 1
2 0 3
1 0 0

read返回值为0表示EOF。

您需要打开非阻塞,因为管道将等待数据可用:

fds[j].fd = open(pipeNameo, O_RDWR | O_NONBLOCK);

首先,您应该确保您实际碰到了管道上的文件末尾

当您打开FIFO(命名管道的另一个名称)进行读取时,进程将等待另一个进程打开它进行写入并写入内容。然后,它将继续等待更多的输入,直到所有打开它进行写入的进程都将其关闭

您可以使用和在两个终端窗口中测试这一点:

在另一个终端:

$ cat > test-fifo   # This is the writing process; type here and see it above
现在,如果关闭写入过程,读取过程将退出,因为它已到达文件的末尾

但是,如果您打开两个写入进程,并且只退出一个进程,FIFO将保持打开状态,而读取端将不会结束,直到您关闭这两个进程

因此,一种很容易犯错误的可能性是,仍然在某个地方打开FIFO进行写入,因此读取端永远不会得到文件结束状态。需要注意的一件事是,如果这个过程本身也有FIFO打开以供写入,或者如果产生数据的任何过程只是保持管道打开,而不是在完成后关闭管道

如果无法确定某个进程是否已打开管道进行写入,请尝试或确定可能已打开管道的任何进程

关于您的代码的一些其他注释,也可能是问题:

char buf[10] ;

read(fd, buf, 1) ;
char curr = buf[0] ;
while (curr != EOF)
这不是确定是否使用低级、无缓冲原语到达文件末尾的方式;这就是使用缓冲stdio操作的方法,比如。使用
read
,您使用所需的读取长度调用它,它返回它可以读取的长度(可能小于您要求的长度)、0(如果它位于文件末尾)和-1(错误时)。如果未检查
读取的返回值
,则存在错误。请注意,并非所有错误都是致命的

即使您使用的是
fgetc
,此代码也是有缺陷的
fgetc
返回一个int,而不是char,因此它可以返回整个字符值范围以及EOF的哨兵值

    printf("BEFORE\n"); // Gets stuck here when EOF, this is the string of output
    read(fd, buf, 1) ;
    printf("AFTER\n") ;
在轮询调用之间,通常不应尝试读取同一文件描述符两次;否则,如果文件描述符上没有更多可用数据,则第二个文件可能会阻塞。相反,您应该对一定数量的数据进行一次读取,但要准备好
read
,以返回比您请求的数据更少的数据,并返回轮询循环,找出现在可用的数据(可能在不同的fd上,如果此fd没有可用的新数据,但另一fd有可用的数据)


使用
read
的方法通常是一次读取整个缓冲区,而不是一次读取一个字符。

问题是,一旦达到EOF,它就不会返回。read()在循环的最后一次迭代中被卡住。我的循环结束时的
printf(“AFTER\n”)
从未打印最后一次,这意味着read()在尝试执行读取并且已经是EOF时永远不会完成。@DavidBaez您的代码从不检查read的返回值。此外,由于您正在从管道读取数据,因此在管道的另一端关闭之前,您不会看到EOF。发生了吗?@DavidBaez如果read()返回0,就不应该再次调用read()。代码需要检查read()的返回值,并处理0(EOF)和-1(错误)的返回值。您还需要确保命名管道的另一端实际上已关闭。在另一端关闭之前不会有EOF。我以前从未听说过fuser和lsof。此外,IMHO这是一个完美的总结,并提示了pipe/fifo的缺陷+谢谢。
char buf[10] ;

read(fd, buf, 1) ;
char curr = buf[0] ;
while (curr != EOF)
    printf("BEFORE\n"); // Gets stuck here when EOF, this is the string of output
    read(fd, buf, 1) ;
    printf("AFTER\n") ;